在加载之前尝试在 DOM 中定位一个元素是行不通的(脚本一遇到它就会运行。如果它在文件中的 html 之上,则该元素将不存在,因此不会被找到)
类似地,触发 AJAX 请求然后将其视为同步操作(在执行更多代码之前等待操作完成)将不起作用。
在第一种情况下,代码是在浏览器解析 HTML 之前遇到的,因此当您尝试获取对它的引用时,该元素在 DOM 中不存在 - 这可以通过等待来修复文件以表明它已完成加载。
第二个问题是在触发birth 函数后,立即触发whereIsTheChildren 函数。不幸的是,ajax 请求仍在等待中,所以我们还没有从它那里得到我们需要使用的结果。这可以通过将调用 whereIsTheChildren 放在 ajax 请求的成功回调中来解决。
我已经做了一个简单的例子,使用 vanilla JS 和 PHP - 只需将 php 文件的请求替换为 CGI 文件。
getKidCount.php
<?php
echo "3";
?>
index.html
<!doctype html>
<html>
<head>
<script>
"use strict";
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
function myAjaxGet(url, successCallback, errorCallback)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function()
{
if (this.readyState==4 && this.status==200)
successCallback(this);
}
ajax.onerror = function()
{
console.log("AJAX request failed to: " + url);
errorCallback(this);
}
ajax.open("GET", url, true);
ajax.send();
}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
//birth(3, byId("Marry") );
myBirth( byId('Marry') );
}
function myBirth(parentElem)
{
myAjaxGet('getKidCount.php', onAjaxSuccess, onAjaxFail);
function onAjaxSuccess(ajax)
{
var numKids = parseInt(ajax.responseText);
for (var i=0; i<numKids; i++)
{
var div = document.createElement('div');
div.id = ("child-"+i);
parentElem.appendChild(div);
}
document.getElementById("test-output-1").innerHTML = parentElem.children.length; // now there are 3 children
whereIsTheChildren();
}
function onAjaxFail(ajax)
{
alert("Ajax failed. :(");
}
}
function whereIsTheChildren()
{
document.getElementById("test-output-2").innerHTML = byId('Marry').children.length; // there are 0 children
}
/*
function birth(xkids, mom)
{
for( var i = 0; i < xkids; i++ )
{
mom.appendChild(document.createElement("div"));
mom.children[i].setAttribute("id", "child-"+i);
}
document.getElementById("test-output-1").innerHTML = mom.children.length; // now there are 3 children
}
function birth(mom)
{
$.ajax(
{url: "/cgi-bin/count.cgi", // return 3 for sure
success: function(xkids) // xkids is 3
{
for( var i = 0; i < xkids; i++ )
{
mom.appendChild(document.createElement("div"));
mom.children[i].setAttribute("id", "child-"+i);
}
document.getElementById("test-output-1").innerHTML = mom.children.length; // now there are 3 children
}
document.getElementById("test-output-2").innerHTML = mom.children.length; // now there are 0 children
}
*/
</script>
</head>
<body>
<div id='test-output-1'></div>
<div id='test-output-2'></div>
<div id='Marry'></div>
</body>
</html>