Javascript 看不到动态生成的元素?
Javascript cannot see dynamically generated elements?
不知道为什么下一个调用的函数看不到新生成的元素?感谢帮助!!
解决方案:添加 async: false 以禁用异步功能,以确保 test-output-2 和 test-output-3 在出生过程后执行。默认情况下,ajax 使用 async: true 就像多线程一样。
function birth(mom)
{
$.ajax(
{url: "/cgi-bin/count.cgi", // return 3 for sure
async: false, // add this to disable asynchronous feature to make sure test-output-2 and test-output-3 executed after birth process
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; // there are 0 children if async: true
}
var marry = document.getElementById("Marry"); // currently no child
birth(marry);
function whereIsTheChildren()
{
document.getElementById("test-output-3").innerHTML = marry.children.length; // there are 0 children if async: true
}
whereIsTheChildren();
你把它放在 window.onload 事件处理程序中了吗?您的代码正在运行,请检查此 fiddle
window.onload=function(){
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
}
var marry = document.getElementById("Marry"); // currently no child
birth(3, marry);
function whereIsTheChildren()
{
document.getElementById("test-output-2").innerHTML = marry.children.length; // there are 0 children
}
whereIsTheChildren();
}
在加载元素之前尝试在 DOM 中定位一个元素是行不通的(脚本会在遇到它时立即运行。如果它在文件中的 html 之上,元素尚不存在,因此不会被发现)
同样,发出 AJAX 请求然后将其视为同步操作(在执行更多代码之前等待操作完成)将不起作用。
在第一个实例中,代码在浏览器有时间解析 HTML 之前遇到,因此当您尝试获取引用时,该元素不存在于 DOM 中到它 - 这可以通过等待文档发出加载完成的信号来解决。
第二个问题是,在触发 birth
函数后,立即触发了 whereIsTheChildren
函数。不幸的是,ajax 请求仍在等待处理,因此我们还没有从中得到我们需要使用的结果。这是通过将对 whereIsTheChildren
的调用放在 ajax 请求的成功 call-back 中来解决的。
我已经快速创建了一个示例,使用 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>
修改为在 DOM 以及 console.log
中表示
function birth(xkids, mom) {
var mom = document.querySelector(mom);
console.log('Mom: '+mom.id);
for (var i = 0; i < xkids; i++) {
mom.appendChild(document.createElement("div"));
mom.children[i].setAttribute("id", "child-" + i);
mom.children[i].innerHTML = mom.children[i].id;
}
console.log(mom.id+' has '+mom.children.length+' children');
var test = document.createElement("output");
document.body.appendChild(test);
test.value = mom.id + ' ' + mom.children.length;
}
birth(3, '#Marry');
birth(5, '#Liz');
birth(2, '#Betty');
div {
outline: 1px solid black;
width: 100px;
height: 30px;
}
output {
outline: 1px solid red;
color: red;
margin: 10px auto;
padding: 2px;
float: left;
}
.mom {
outline: 1px dashed blue;
width: 100px;
height: auto;
padding: 5px;
display: inline-block;
}
<div id="Marry" class="mom">Marry</div>
<div id="Liz" class="mom">Liz</div>
<div id="Betty" class="mom">Betty</div>
不知道为什么下一个调用的函数看不到新生成的元素?感谢帮助!! 解决方案:添加 async: false 以禁用异步功能,以确保 test-output-2 和 test-output-3 在出生过程后执行。默认情况下,ajax 使用 async: true 就像多线程一样。
function birth(mom)
{
$.ajax(
{url: "/cgi-bin/count.cgi", // return 3 for sure
async: false, // add this to disable asynchronous feature to make sure test-output-2 and test-output-3 executed after birth process
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; // there are 0 children if async: true
}
var marry = document.getElementById("Marry"); // currently no child
birth(marry);
function whereIsTheChildren()
{
document.getElementById("test-output-3").innerHTML = marry.children.length; // there are 0 children if async: true
}
whereIsTheChildren();
你把它放在 window.onload 事件处理程序中了吗?您的代码正在运行,请检查此 fiddle
window.onload=function(){
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
}
var marry = document.getElementById("Marry"); // currently no child
birth(3, marry);
function whereIsTheChildren()
{
document.getElementById("test-output-2").innerHTML = marry.children.length; // there are 0 children
}
whereIsTheChildren();
}
在加载元素之前尝试在 DOM 中定位一个元素是行不通的(脚本会在遇到它时立即运行。如果它在文件中的 html 之上,元素尚不存在,因此不会被发现)
同样,发出 AJAX 请求然后将其视为同步操作(在执行更多代码之前等待操作完成)将不起作用。
在第一个实例中,代码在浏览器有时间解析 HTML 之前遇到,因此当您尝试获取引用时,该元素不存在于 DOM 中到它 - 这可以通过等待文档发出加载完成的信号来解决。
第二个问题是,在触发 birth
函数后,立即触发了 whereIsTheChildren
函数。不幸的是,ajax 请求仍在等待处理,因此我们还没有从中得到我们需要使用的结果。这是通过将对 whereIsTheChildren
的调用放在 ajax 请求的成功 call-back 中来解决的。
我已经快速创建了一个示例,使用 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>
修改为在 DOM 以及 console.log
中表示function birth(xkids, mom) {
var mom = document.querySelector(mom);
console.log('Mom: '+mom.id);
for (var i = 0; i < xkids; i++) {
mom.appendChild(document.createElement("div"));
mom.children[i].setAttribute("id", "child-" + i);
mom.children[i].innerHTML = mom.children[i].id;
}
console.log(mom.id+' has '+mom.children.length+' children');
var test = document.createElement("output");
document.body.appendChild(test);
test.value = mom.id + ' ' + mom.children.length;
}
birth(3, '#Marry');
birth(5, '#Liz');
birth(2, '#Betty');
div {
outline: 1px solid black;
width: 100px;
height: 30px;
}
output {
outline: 1px solid red;
color: red;
margin: 10px auto;
padding: 2px;
float: left;
}
.mom {
outline: 1px dashed blue;
width: 100px;
height: auto;
padding: 5px;
display: inline-block;
}
<div id="Marry" class="mom">Marry</div>
<div id="Liz" class="mom">Liz</div>
<div id="Betty" class="mom">Betty</div>