我正在构建一个单页应用程序,它的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。