运行 jQuery DOM 元素上的脚本加载了 AJAX

Running jQuery scripts on DOM elements loaded with AJAX

我知道当 DOM 内容通过 AJAX 加载时 jQuery 不会 运行。但是我对原因感到困惑。我的理解是 DOM 元素在 jQuery 启动时不存在,因此它找不到正确的 ID 或 classes.

但我有一种情况,jQuery 仅在通过 AJAX 加载所有内容后才被调用。但是还是不行。

这是我的代码。我试图在 AJAX 完成后将函数 decorateGains() 变为 运行。

loadData('7-days'); // Runs the default AJAX for 7 days
function loadData(type){
    var xmlhttp;
    if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}
    else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
    xmlhttp.onreadystatechange=function()
      {
        if (xmlhttp.readyState==4 && xmlhttp.status==200){document.getElementById("home-table").innerHTML=xmlhttp.responseText;}
      }
    xmlhttp.open("GET","actions/get-data-"+type+".php",true);
    xmlhttp.send();
    decorateGains();
}

您可以看到我在 loadData() 函数的末尾添加了对函数 decorateGains() 的调用。

decorateGains() 函数 执行 运行,因为我可以看到我的控制台消息。但是它没有完成它应该完成的任务。

function decorateGains() {
    console.log('here');
    $(".gains").each(function() { 
        var num = +($(this).text());
        if (num > 0) {
            console.log('here');
            $(this).addClass("positive");
        }
        if (num < 0) {
            console.log('here');
            $(this).addClass("negative");
        }
    });
}

(脚本搜索class为.gains的所有元素,并根据内容添加新的positivenegative的class元素的。本质上,它将 .gains 元素装饰为红色或绿色,具体取决于数字是负数还是正数)。

这是因为 AJAX 调用是异步的。当您调用 decorateGains() 函数时,请求尚未完成(因此新内容尚未附加到 DOM)。在设置 innerHTML:

之后,您需要将对函数的调用放在 onreadystatechange 处理程序中
loadData('7-days'); // Runs the default AJAX for 7 days
function loadData(type) {
    var xmlhttp;
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            document.getElementById("home-table").innerHTML = xmlhttp.responseText;

            decorateGains(); // <-- move this in here
        }
    }
    xmlhttp.open("GET", "actions/get-data-" + type + ".php", true);
    xmlhttp.send();
}