如何防止整数onreadystatechange的更改

时间:2016-12-17 17:37:05

标签: javascript php html ajax

我的Ajax存在问题。目前,我有5对元素:下拉列表(span标签)和下拉列表的内容(ul标签)。在span标记上是onclick的事件监听器,如果单击则显示drop-downs,在其他位置单击时,下拉菜单将消失。使用硬编码的li,下拉列表工作正常。但是,我尝试使用ajax使用动态生成的<ul>填充<li> s。但是,Ajax行为不端。

span上我还有另一个onchange的事件监听器,它调用js函数calloptions();,这是我的Ajax。我想要实现的是,如果您选择一个选项,其他下拉菜单中的选项会根据您选择的内容而更改。我所具有的功能是onchange,从下拉列表0循环到下拉列表5,根据所有选择的值更改<li>

但是,当我调试时,我的值[k]会在第一个循环中5到达readyState时变为[4]?我不确定第1循环中[k]值的增加是由于onreadystatechange还是其他完全错过的结果。因此,这会导致函数无法覆盖<ul>值,因为它正在查找span[5],而只有5 Cannot read property 'parentElement' of undefined (...),然后打印 <div id="filters"> <div class="i_drop col column-2"> <span class="i_drop_select"></span> <img class="i_drop_select_function drop" src="./assets/drop_input.png"> <ul class="i_drop_content"></ul> </div> <div class="i_drop col column-2"> <span class="i_drop_select"></span> <img class="i_drop_select_function drop" src="./assets/drop_input.png"> <ul class="i_drop_content"></ul> </div> <div class="i_drop col column-2"> <span class="i_drop_select"></span> <img class="i_drop_select_function drop" src="./assets/drop_input.png"> <ul class="i_drop_content"></ul> </div> <div class="i_drop col column-2"> <span class="i_drop_select"></span> <img class="i_drop_select_function drop" src="./assets/drop_input.png"> <ul class="i_drop_content"></ul> </div> <div class="i_drop col column-2"> <span class="i_drop_select"></span> <img class="i_drop_select_function drop" src="./assets/drop_input.png"> <ul class="i_drop_content"></ul> </div> </div>

HTML

function calloptions() { 
var toselect = ["class", "topic", "subtopic", "year", "marks"];
for (var k = 0; k < toselect.length; k++) {

    var filters = document.getElementById("filters"); 
    var span = filters.getElementsByTagName("span");
    var execute = "select";
    var myclass= span[0].innerHTML;
    var topic =span[1].innerHTML;
    var subtopic = span[2].innerHTML;
    var year = span[3].innerHTML;
    var marks =span[4].innerHTML;

    makeRequest('test.php', toselect[k],  myclass, topic, subtopic, year, marks, execute); 

    function makeRequest(url, select, myclass, topic, subtopic, year, marks, execute) {

    httpRequest = new XMLHttpRequest();

    if (!httpRequest) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
            return false;
    }

    httpRequest.open('POST', url);
    httpRequest.onreadystatechange = alertContents;
    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
    httpRequest.send("function="+ execute+ "&toselect="+ select+ "&class=" + encodeURIComponent(myclass) + "&topic=" + encodeURIComponent(topic) + "&subtopic=" + encodeURIComponent(subtopic) + "&year=" + encodeURIComponent(year) + "&marks=" + encodeURIComponent(marks));
    }

    function alertContents() {
        if (this.readyState == 4 && this.status == 200) {
            var response = this.responseText;
            var container = span[k].parentElement || span[k].parentNode ;
            var ul =container.getElementsByTagName("ul")[0];
            ul.innerHTML = response;
        }
    }
}
}

AJAX

if(!empty($_POST['function']) && !empty($_POST['toselect']))
{
    $toselect = $_POST['toselect'];
    $_POST['function']($toselect);

}

function select($toselect) {
    global $link;

    $variables = "";

    $select_options = array("class", "topic", "subtopic", "year", "marks");     

    $unset_options= array(); $set_options= array(); $set_values= array();

    for ($i=0; $i < count($select_options) ; $i++) { 
        if(isset($_POST[$select_options[$i]]) && $_POST[$select_options[$i]] != ''){
            array_push($set_options, $select_options[$i]);
        } else {
            array_push($unset_options, $select_options[$i]);
        }
    }

    for ($i=0; $i < count($set_options) ; $i++) { 
        array_push($set_values, $_POST{$set_options[$i]});
    }

    for ($i=0; $i < count($unset_options); $i++) { 
        $key = array_search ( $unset_options ,  $select_options);

        unset($select_options[$key]);
    }

    $select_options = array_values($select_options);

    for ($i=0; $i < count($set_options) ; $i++) { 
        if ($i<1) {
            $variables .= " $set_options[$i]='$set_values[$i]'";
        } else {
            $variables .= " AND $set_options[$i]='$set_values[$i]'";
        }
    }

    if ($variables != "") {
        $variables = "WHERE" . $variables;
    }

    $sql="SELECT DISTINCT $toselect FROM `questions` $variables";

    $result=mysqli_query($link, $sql);

    $test_array = array();

    $i = 0;

    while ($row =mysqli_fetch_array($result)) {
        $test_array[$i] = "<li>$row[0]</li>";
        $i++;
    }

    $test_array = implode("", $test_array);

    echo $test_array;       
}

PHP

httpRequest.send()

我在$_GET打印了提交给PHP文件的参数,并在文件中将它们作为System.Net.WebRequest req = null; System.Net.WebResponse rsp = null; System.IO.StreamWriter writer; System.IO.StreamReader Reader; String responseFromServer; String uri; String txtXMLData; String AccountId; String Password; String SecureHashSecretKey; String SenderName; String MSISDN; String SMSMessage; try { AccountId = "xxxxx"; Password = "xxxxx"; SecureHashSecretKey = "xxxxx"; SenderName = "xxxxx"; MSISDN = "xxxxx"; SMSMessage = "Test SMS"; uri = "https://e3len.vodafone.com.eg/web2sms/sms/submit/"; txtXMLData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SubmitSMSRequest xmlns:=\"http://www.edafa.com/web2sms/sms/model/\""+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+ "xsi:schemaLocation=\"http://www.edafa.com/web2sms/sms/model/ SMSAPI.xsd \" xsi:type=\"SubmitSMSRequest\">"+ "<AccountId>"+AccountId+"</AccountId>"+ "<Password>"+Password+"</Password>"+ "<SecureHash>"+SecureHashSecretKey+"</SecureHash>"+ "<SMSList>"+ "<SenderName>"+SenderName+"</SenderName>"+ "<ReceiverMSISDN>"+MSISDN+"</ReceiverMSISDN>"+ "<SMSText>"+SMSMessage+"</SMSText>"+ "</SMSList>"+ "</SubmitSMSRequest>"; req = System.Net.WebRequest.Create(uri); req.Method = "POST"; req.ContentType = "text/xml"; writer = new System.IO.StreamWriter(req.GetRequestStream()); writer.WriteLine (txtXMLData); writer.Close (); rsp = req.GetResponse(); Reader = new System.IO.StreamReader(rsp.GetResponseStream()); responseFromServer = Reader.ReadToEnd(); rsp.Close(); Reader.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } 运行,并且它有效,所以我知道这不是PHP的问题,而是我的Ajax失败了。

我将非常感谢您使用任何更简单的算法/方法来实现预期目标,但我会非常感激,有助于消除我当前的错误。我是Ajax和javascript的新手,因此,也会非常欣赏一点。谢谢!

2 个答案:

答案 0 :(得分:1)

目前,我还没有找到导致我的“过度增加”[k]值的原因,但是从实验中分离for循环和Ajax工作。像这样:

function externalFunction() {

    var toselect = ["class", "topic", "subtopic", "year", "marks"];
    for (var i = 0; i < toselect.length; i++) {
        calloptions(i, toselect[i]);
    }
}


function calloptions(x, toselect) { 

    var form = document.getElementById("filters"); 
    var span = form.getElementsByTagName("span");
    var execute = "select";
    var myclass= span[0].innerHTML;
    var topic =span[1].innerHTML;
    var subtopic = span[2].innerHTML;
    var year = span[3].innerHTML;
    var marks =span[4].innerHTML;

    makeRequest('test.php', toselect,  myclass, topic, subtopic, year, marks, execute); 

    function makeRequest(url, toselect, myclass, topic, subtopic, year, marks, execute) {

        httpRequest = new XMLHttpRequest();

        if (!httpRequest) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
            return false;
        }

        httpRequest.onreadystatechange = alertContents;
        httpRequest.open('POST', url);
        httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
        httpRequest.send("function="+ execute+ "&toselect="+ toselect+ "&class=" + encodeURIComponent(myclass) + "&topic=" + encodeURIComponent(topic) + "&subtopic=" + encodeURIComponent(subtopic) + "&year=" + encodeURIComponent(year) + "&marks=" + encodeURIComponent(marks));
}

    function alertContents() {
        if (this.readyState == 4 && this.status == 200) {
            var response = this.responseText;
            var container = span[x].parentElement || span[x].parentNode ;
            var ul =container.getElementsByTagName("ul")[0];
            ul.innerHTML = response;
    }
}

但搜索仍然没有结束,仍然试图弄清楚......

答案 1 :(得分:0)

k的值增加不是由于某些神秘的ajax / scope问题,实际上是由于for循环。 k即使在增加时也会增加 你的病情失败是的!你听到它是对的,我承认这真的很奇怪。当你循环超过k已经等于5注意到atm。还没有回复。由于你所有的回调功能都是相同的,所以它们都引用了相同的k,它们的值为5,这就是你看错误的原因

for (var k = 0; k < toselect.length; k++) {
//....
//
}

console.log(k); //5

你能做什么? 那么你可以在你的回调函数中简单地使用k-1或者只是使用其他一些变量来增加它但是这只会消除这个错误并且仍然会有错误,因为当响应到来时它们都会看到k具有相同的值并且更新相同<span>。解决异步问题。我们通常使用闭包的问题尝试搜索,如果你有任何疑问,你可以问我。