我有三个HTML DropDownList
(<select><option></option></select>
)。第一个DropDownList
包含类别,第二个包含不同产品的子类别,第三个包含品牌(或制造商)。
当选择某个类别时,应根据传递给Ajax函数的类别ID,从数据库中一次填充两个下拉子类别和品牌。我正在使用以下Ajax代码。
function ajax()
{
if(window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp = new ActivexObject("Microsoft.XMLHTTP");
}
}
function getBrandList(selected) //selected is the category id.
{
ajax();
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("brandList").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","ajax/BrandAjax.php?selected="+selected, true);
xmlhttp.send();
alert(selected);
}
function getSubcategoryList(selected) //selected is the category id.
{
getBrandList(selected); //First above function is invoked to populate brands.
ajax();
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("subCategoryList").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","ajax/SubCatAjax.php?selected="+selected, true);
xmlhttp.send();
}
选择类别后,将调用getSubcategoryList(selected)
Javascript函数来执行Ajax请求。问题是我需要立即填充子类别和品牌下拉(当选择一个类别时)。
它正在工作,并且根据传递的类别ID(它是上述函数selected
的参数)立即填充下拉列表。
我不必在函数getBrandList()
底部使用警告框。注释此警报框时,只会填充一个子类别的下拉列表。品牌仍然是空的。我不再需要这个警报框了。
为什么会这样?解决方案是什么?
答案 0 :(得分:2)
我认为第二个ajax()调用正在消灭xmlhttp变量。当你把警报放进去的时候,我打赌它会在开始第二次通话之前给你第一个通话时间。您可能应该先调用ajax()并从处理程序中删除该调用。
答案 1 :(得分:2)
首先,建议您尝试一些现代的JavaScript框架,比如JQuery。
@tzerb如何说:在第一次AJAX请求完成之前覆盖全局变量xmlhttp。您必须使用局部变量。
function ajax()
{
var xmlhttp; //!!
if(window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp = new ActivexObject("Microsoft.XMLHTTP");
}
return xmlhttp; //!!
}
function getBrandList(selected) //selected is the category id.
{
xmlhttp = ajax(); //!!
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("brandList").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","ajax/BrandAjax.php?selected="+selected, true);
xmlhttp.send();
//alert(selected);
}
function getSubcategoryList(selected) //selected is the category id.
{
getBrandList(selected); //First above function is invoked to populate brands.
xmlhttp = ajax(); //!!
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("subCategoryList").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","ajax/SubCatAjax.php?selected="+selected, true);
xmlhttp.send();
}
使用JQuery,您的代码可能如下所示:
function getBrandsList(selected){
$("#brandList").load("ajax/BrandAjax.php?selected="+selected);
}
function getSubcategoryList(selected){
$("#brandList").load("ajax/SubCatAjax.php?selected="+selected);
}
答案 2 :(得分:1)
我建议您使用jQuery。
1. Load the first dropdown with categories on page load
2. Call the following ajax call on change event of the first dropdown, categoryList
$('#categoryList').change(function () {
$('#subCategoryList').load("ajax/SubCatAjax.php?selected="+this.value);
$('#brandList').load("ajax/BrandAjax.php?selected="+$('#subCategoryList').val());
});
3. Call the following ajax call on change event of the second dropdown, subcategoryList.
$('#subCategoryList').change(function () {
$('#brandList').load("ajax/BrandAjax.php?selected="+this.value);
});
P.S。我假设你的ajax请求返回包含选项的字符串,例如。 <option value='1'>subcategory1</option><option value='2'>subcategory2</option>
..等等。并且您希望根据所选的子类别而非所选类别加载品牌。
答案 3 :(得分:1)
我认为您可以使用回叫功能。但我确实建议使用jquery。它简单得多。你不需要手动完成所有操作。(创建xhttprequest对象并维护响应状态和所有那些笨拙的activex对象相关的东西)
答案 4 :(得分:1)
seriyPS基本上达到了目标。问题实际上是xmlhttp变量。您需要在每个正在使用的函数中声明它是本地的。基本上,为函数调用创建一个闭包。然而,问题不一定是它需要“本地”,而是作为全局变量在第二个请求中重新定义。这基本上会终止初始请求,因为变量现在指向第二个请求。
警报框使其工作的原因是因为第一个请求正在完成ajax请求,然后才能“点击”确定。 (警报框将暂停javascript执行,因此延迟第二个请求,直到您单击确定。)
要解决此问题,您可以修改代码以为每个请求使用不同的变量。尝试将您的功能更改为以下内容:
// Global Variables
var brandListRequest;
var subcategoryRequest;
function ajax()
{
var xmlhttp; //!!
if(window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp = new ActivexObject("Microsoft.XMLHTTP");
}
return xmlhttp; //!!
}
function getBrandList(selected) //selected is the category id.
{
brandListRequest = ajax(); //!!
brandListRequest.onreadystatechange=function()
{
if(brandListRequest.readyState==4 && brandListRequest.status==200)
{
document.getElementById("brandList").innerHTML=brandListRequest.responseText;
}
}
brandListRequest.open("GET","ajax/BrandAjax.php?selected="+selected, true);
brandListRequest.send();
//alert(selected);
}
function getSubcategoryList(selected) //selected is the category id.
{
getBrandList(selected); //First above function is invoked to populate brands.
subcategoryRequest = ajax(); //!!
subcategoryRequest.onreadystatechange=function()
{
if(subcategoryRequest.readyState==4 && subcategoryRequest.status==200)
{
document.getElementById("subCategoryList").innerHTML=subcategoryRequest.responseText;
}
}
subcategoryRequest.open("GET","ajax/SubCatAjax.php?selected="+selected, true);
subcategoryRequest.send();
}