无法从文档就绪事件处理程序访问动态命名的元素



我正在构建一个单页应用程序,它的html主体从一个简单的容器开始

<body>
<div id="main-container" class="main-container">
    <div id="accordion">
    <!-- Bouts will be inserted here -->
    </div>
    <button id="myButton" type="button">Click Me!</button>
</div>
</body>

我有一个文档就绪的事件处理程序,它获取一个JSON文件并迭代加载的集合,该集合包含可变数量的条目。

$.getJSON("data/event.json", function (data) {
$.each(data, function (key, val) {
      $("#accordion").append(addBout(val, key)).accordion("refresh");
    });
});

addBout()方法构建一个div元素(这是一个手风琴部分),其中包含几个动态命名的span元素。

示例:

"<span id="current_round_" + (key+1) + "">1</span>"

因此,跨度的实际id是current_round_1、current_round_2等。

访问这些跨度:

alert($("#current_round_1").html());

在文档就绪事件处理程序中失败。

我还尝试从window.bind()访问元素

$(window).bind("load", function() {
   // code here
});

这也会失败。

但是,如果我在页面中添加一个按钮,并访问该按钮的单击事件处理程序中的元素。。。。。

$("#myButton").click(function() {
        alert($("#current_round_1").html());
    });

有人能提出为什么当DOM准备好时,甚至当它被"加载"但以后可以手动访问时,动态命名的元素不可用吗?

提前谢谢。

它失败了,因为您的动态生成元素在文档就绪时还不可用。生成它们的代码异步运行,所以如果你有这样的东西:

$(document).ready(function () {
    $.getJSON("data/event.json", function (data) {
        $.each(data, function (key, val) {
            $("#accordion").append(addBout(val, key)).accordion("refresh");
        });
    });
    alert($("#current_round_1").html());
});

alert(...)将在$.getJSON(...)执行回调之前执行。当您将按钮与单击处理程序一起使用时,它之所以有效,是因为在异步调用返回之前,您极不可能单击该按钮。如果你添加了某种延迟,使通话需要更长的时间才能返回,那么点击按钮就会失败。

一个解决方案是添加一个函数,该函数可以对动态元素执行任何需要执行的操作:

var doStuff = function () {
    alert($("#current_round_1").html());
};

然后让$.getJSON(...)回调在呈现跨度后执行该方法:

$(document).ready(function () {
    $.getJSON("data/event.json", function (data) {
        $.each(data, function (key, val) {
            $("#accordion").append(addBout(val, key)).accordion("refresh");
        });
        doStuff(); // <-- won't be executed until the elements have been rendered
    });
});

我的猜测是,问题是窗口加载事件在AJAX调用完成之前触发,因此在任何div插入到dom 之前触发

添加对象后需要绑定,或者使用.on()和delegate。

$('#accordion').on('click', 'span', function(){})

好吧,当文档准备就绪时,文档准备就绪会触发——只有HTML文档没有依赖项。这是第一个DOM。然后更改DOM和document.ready仍然是空的。该按钮的工作原理与您单击它时DOM的工作原理相同

创建大量元素并写出动态ID以稍后再次使用$()获取它们,这感觉有点迂回。为什么不在创建元素时存储它们的引用呢?这样,您就可以将它们缓存在对象中,而不需要再次从DOM中读取,这可能会很慢。

本质上:获得对元素的引用的正确时间是在循环完成时,在此之前元素不存在。

我还建议您不要在每次迭代中追加,而是构建一个字符串(使用concat或其他任何东西),直到循环完成,然后设置html(或追加)整个字符串。至于最初的问题,您的问题是DOMContentReady在Ajax调用返回并且新内容在DOM中之前激发。您需要对Ajax请求的成功状态(success:function(){})进行回调,并让该函数对数据进行迭代,并将最后一个字符串插入DOM。

最新更新