2016-12-17 57 views
4

我遇到了問題與我的Ajax。目前,我有5對元素:下拉框(span標籤)和下拉框內容(ul標籤)。在span標籤是一個事件監聽器,爲onclick,其中,如果點擊了drop-downs出現,當其他地方點擊,下拉消失。與硬編碼li的下拉菜單工作正常。但是,我試圖用動態生成<li> s使用ajax來填充<ul>。但是,阿賈克斯是行爲不端。如何防止整數onreadystatechange的變化

span我還有另一個事件偵聽器onchange,它調用js函數calloptions();,這是我的Ajax。我試圖實現的是,如果您選擇一個選項,則其他下拉菜單中的選項將根據您選擇的內容進行更改。我有這個功能的是onchange,從下拉0到下拉5循環改變<li>的基於所有選擇的值是什麼。

當我調試時,但是,我的值[k]更改爲5的時間readyState得到[4]在第一個循環?我不確定環路1上[k]的值增加是由於onreadystatechange還是其他我完全不知道的結果。因此,這將導致功能暫時無法因爲它正在尋找span[5]覆蓋<ul>值,而現在只有5人,然後打印Cannot read property 'parentElement' of undefined (...)

HTML

<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> 

AJAX

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; 
     } 
    } 
} 
} 

PHP

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;  
} 

我打印在httpRequest.send()被提交到PHP文件中的參數和運行它們的文件中$_GET,和它的作品,所以我知道它不是一個與PHP的問題,而是對我的Ajax失敗。

我很感激任何簡單的算法/方法來達到預期目標的援助,但會更加欣賞,以消除我的當前錯誤幫助。我對Ajax和JavaScript都很陌生,因此也非常感謝一些沮喪。謝謝!

+0

使異步參數'FALSE'在'。開()'方法,是這樣的:'httpRequest.open( 'POST',網址,FALSE);'。如果您將異步參數設置爲false,則不要編寫任何onreadystatechange函數,只需將代碼放在'.send()'之後。 –

+1

我沒有完全測試過你的想法,但是從我實現的內容來看,我得到一個錯誤,說主線程上的同步XMLHttpRequest由於對最終用戶體驗的有害影響而不推薦使用。如需更多幫助,請查看https:// xhr.spec.whatwg.org /。雖然它可能有效,但它已被棄用。我想找出一種有效的方法來實現這一點,爲未來的知識...無論如何。 –

回答

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; 
    } 
} 

搜索仍然沒有結束,雖然,仍然試圖弄明白......

+0

請看我的答案 – Viney

1

k值即增量是不是由於某種神祕的AJAX /範圍問題它實際上是由於for循環。 即使在 您的病情失敗時,k也會增加是的!你聽到它是正確的,我承認這真的很奇怪。當你循環結束時k已經等於5注意到atm。還沒有迴應。由於所有的回調都在同一個函數它們都指具有價值5這就是爲什麼你看到你可以做什麼錯誤

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

console.log(k); //5 

相同k? 那麼你可以在你的回調函數的簡單使用k-1或者只是使用一些其他的變量增加它自己,但那樣只會刪除這個錯誤,還是因爲當響應來,他們都將參見k具有相同的價值和更新相同<span>是馬車。解決異步。我們通常使用關閉的問題嘗試搜索,如果你有任何疑問,你可以問我。