Javascript看不到动态生成的元素?

标签 javascript ajax dom element

不知道为什么新生成的元素不能被next调用的函数看到?感谢帮助!! 解决方案:添加 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();

最佳答案

尝试在加载之前在 DOM 中定位元素是行不通的(脚本一遇到它就会运行。如果它位于文件中的 html 之上,则该元素尚不存在,因此不会被发现)

类似地,启动 AJAX 请求然后将其视为同步操作(在执行更多代码之前等待操作完成)也是行不通的。

在第一个实例中,在浏览器有时间解析 HTML 之前就遇到了代码,因此当您尝试获取对该元素的引用时,该元素在 DOM 中不存在 - 这可以通过等待来解决文档以表明其已完成加载。

第二个问题是,在触发 birth 函数后,立即触发 whereIsTheChildren 函数。不幸的是,ajax 请求仍然处于待处理状态,因此我们还没有得到我们需要使用的结果。通过将调用 whereIsTheChildren 放在 ajax 请求的成功回调中可以解决此问题。

我使用普通 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>

关于Javascript看不到动态生成的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34585580/

相关文章:

javascript - md-datepicker 从数组中过滤日期

php - 4 分钟后出现横幅

javascript - Ios 设备, "required"字段和感谢消息

javascript - 如何在给定格式的 HTML 列表中显示 jQuery 数据值?

javascript - 对于唯一的 dom 元素总是使用 live() 而不是 bind() 的缺点?

javascript - Android - 使用 JSOUP 解析 JS 生成的 url

javascript - 使用 jquery 动画背景图像

xml - LISP 下载和解析 XML

javascript - 当我单击 X 时,为什么所有项目都会从 Backbone.js View 中删除

javascript - 通过预处理运行 javascript