簡體   English   中英

用AJAX加載div后無法執行Javascript代碼

[英]Javascript code not executing after loading div with AJAX

我有一個名為landscape.php的php文件。 在這里,我調用了另一個名為colorList.php的php文件。 在此文件中,我有3個按鈕來選擇顏色數量:4,5和6。單擊任何按鈕時,我都會調用一個js文件,該文件具有ajax函數,以在div = container中顯示正確的選擇集。

Landscape.php

<table width="980">
<tr>
<td width="1000" style="vertical-align: top">
    <?php include('colorList.php'); ?>
</td>
    <td width="700" style="vertical-align: top">
    <div id="contenido">
    </div>
    </td>
</tr>
</table>

code.js

function showData(dataType)
{

    var capa=document.getElementById("content");

    var ajax=newAjax();

    ajax.open("POST", "test.php", true);
    ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    ajax.send("d="+dataType);

    ajax.onreadystatechange=function()
    {
        if (ajax.readyState==4)
        {
            capa.innerHTML=ajax.responseText;
        }
    }
}

在test.php中,如果dataType為1,則顯示4個選擇;如果2,則選擇5;如果3,則選擇6。 所有這些都具有使用mysql從數據庫中檢索到的顏色列表。 想法是不要在任何選擇器中重復任何顏色,為此,我禁用了已使用此腳本選擇的任何顏色:

function loadColors() { 
                for (i = 0;i < document.test.elements.length;i++) {
                    for (j = 0;j < document.test.elements[i].options.length;j++) {
                        document.test.elements[i].options[j].disabled = false;
                        for (k = 0;k < document.test.elements.length;k++) {
                            if (i != k) {
                                if (document.test.elements[i].options[j].text == document.test.elements[k].options[document.test.elements[k].selectedIndex].text)
                                    document.test.elements[i].options[j].disabled = true;                               
                            }
                        }       
                    }
                }               
            }   

然后,選擇器的定義如下:

<select name="color1" id="color1" onchange="loadColors()">

如果我不使用ajax調用,則此代碼可以正常工作。 也就是說,例如,如果我將所有內容加載到單個php頁面中,則將我在test.php中擁有的內容復制並粘貼到landscape.php中,則一切正常。 但是,只要我使用AJAX加載該內容,就不會。

我的問題不是javascript或php,原因是工作正常。 我的問題是,只要將AJAX添加到方程式中,它就會停止工作。 因此,我想這是調用loadColors()函數的問題。 我嘗試將代碼包含在landscape.php,test.php中,調用code.js(其中ajax和loadColors函數所在的位置),將該腳本加載到landscape.php主體中,但是什么也沒有...

有什么幫助嗎?

正如我在評論中所說,問題出在我自己的選擇上。 選擇是通過AJAX調用創建的,對嗎? 在那種情況下,將永遠不會真正處理選擇上的onchange =“ ...”。 此類DOM事件在頁面加載時處理。 頁面加載后,可以將DOM視為靜態-您可以在DOM中添加或刪除DOM,但是如果您向頁面添加元素並嘗試通過DOM向該新元素添加事件處理程序,則該DOM不會處理。

取而代之的是,您可能想看看如何附加該偵聽器。 首先,我將完全刪除onchange。 沒有幫助 這些是動態元素。 為了讓您的DOM偵聽動態元素的更改,請將事件本身附加到該元素的靜態祖先。 就您的代碼而言,如何將事件附加到偵聽選擇內容更改的容器? 嘗試這樣的事情:

// make these available to both functions.
var capa, selectedOptions;

function showData(dataType)
{
    capa=document.getElementById("content");
    var ajax=newAjax();

    ajax.open("POST", "test.php", true);
    ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    ajax.send("d="+dataType);

    ajax.onreadystatechange=function()
    {
        if (ajax.readyState==4)
        {
            capa.innerHTML=ajax.responseText;
            capa.addEventListener("change", filterSelects);
        }
    }
};

然后,可以像下面這樣使用filterSelects:

 var myContainer = document.querySelector(".container"); var selectOptions = []; myContainer.addEventListener("change", filterSelects); /*** * The above code simply sets the stage, * implementing the filterSelects function * in much the same way you would for els * added via AJAX. Note that, as the rest * of your code seems to be going vanilla, * I've rewritten this to be pure vanilla * and not jQuery. ***/ function filterSelects(event) { if(!event.target.matches("select")) return; var workingEl = event.target; var allSelectEls = document.querySelectorAll(".colorSelector"); // First, we'll iterate through the select els, and figure out the // index of the currently active el. This will be the index of that // select in the collection, and will also be used as the index in the // selectOptions array. for (var i=0; i<allSelectEls.length; i++){ // if we are currently looping over the active select... if (allSelectEls[i] == workingEl) { // ... and it has an actual working value if (workingEl[workingEl.selectedIndex].value != "...") { selectOptions[i] = workingEl[workingEl.selectedIndex].value; } else { selectOptions[i] = null; } } // also, while we're here, we'll re-enable all options. for (var j=0; j<allSelectEls[i].options.length; j++){ allSelectEls[i].options[j].removeAttribute("disabled"); } } /***** * jQuery makes this so easy, but here it is as vanilla JS * we will loop through every one of our selectOptions * (remember, that's an array of the select values), and * run an inner loop going through all select elements, * and inside THAT loop through each option in the current select. * loop 'i' = the selectOptions array * loop 'j' = the select collection * loop 'k' = the options in the current select *****/ for (var i=0; i<selectOptions.length; i++){ var currentOptionToDisable = selectOptions[i]; for (var j = 0; j<allSelectEls.length; j++){ var currentSelectEl = allSelectEls[j]; // If the current selectOption is NOT from the current select if (i !== j) { for (var k = 0; k<currentSelectEl.options.length; k++) { currentSelectOption = currentSelectEl.options[k]; // if the value in selectOption = the value of the current option if(currentSelectOption.value == currentOptionToDisable) { // we disable that option. currentSelectOption.disabled = true; } } } } } }; 
 <div class="container"> <select name="color1" id="color1" class="colorSelector"> <option>...</option> <option value="red">Red</option> <option value="orange">Orange</option> <option value="yellow">Yellow</option> <option value="green">Green</option> <option value="blue">Blue</option> <option value="indigo">Indigo</option> <option value="violet">Violet</option> </select> <select name="color2" id="color0" class="colorSelector"> <option>...</option> <option value="red">Red</option> <option value="orange">Orange</option> <option value="yellow">Yellow</option> <option value="green">Green</option> <option value="blue">Blue</option> <option value="indigo">Indigo</option> <option value="violet">Violet</option> </select> <select name="color3" id="color3" class="colorSelector"> <option>...</option> <option value="red">Red</option> <option value="orange">Orange</option> <option value="yellow">Yellow</option> <option value="green">Green</option> <option value="blue">Blue</option> <option value="indigo">Indigo</option> <option value="violet">Violet</option> </select> </div> 

請注意,在我的工作示例中,我沒有將事件附加到動態元素本身。 你不能 如果您希望他們工作,那就不是。 相反,我在這些動態元素的STATIC父級上創建了一個偵聽器。 然后,在處理函數中,我可以檢查change事件的目標是否是我想要的目標,無論是matchs('select')還是通過檢查類或其他方法。 但是重要的一點是,如果我添加或刪除更多選擇,則偵聽器將附加到DOM的靜態部分,並且不會受到這種惡作劇的影響。

另請注意,由於這是一個小問題,因此我沒有將聽眾附加到文檔或正文上。 找到最近的靜態祖先,嘗試將您的代碼封裝在盡可能小的部分。 那只是我的肥皂盒,也許有一天我會抱怨。 但是請注意,我已連接到容器,並且要監聽該容器,而不是文檔或正文。 只是說。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM