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

时间:2014-04-17 13:18:02

标签: jquery

我正在构建一个单页应用,其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准备就绪时,动态命名的元素不可用,或者甚至当它被加载时#34;但以后可以手动访问吗?

提前致谢。

5 个答案:

答案 0 :(得分:3)

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

$(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
    });
});

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您需要在添加对象后绑定或使用.on()和委托。

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

答案 3 :(得分:0)

好吧,文档就绪时文档就绪了 - 只有没有依赖项的HTML文档。这是第一个DOM。然后你改变DOM和document.ready仍然是空的。按钮的工作原理是DOM在您单击它时完成。

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

本质上:获得元素引用的正确时间是在你的循环结束时,元素不存在之前。

答案 4 :(得分:0)

我还建议你不要追加每次迭代,而是建立一个字符串(带有concat或其他),直到循环完成,然后设置html(或追加)整个字符串。至于你原来的问题,你的问题是DOMContentReady在你的Ajax调用返回之前触发,你的新内容在DOM中。您需要在Ajax请求的成功状态(success:function(){})上触发回调,并让该函数迭代您的数据并将最终字符串插入DOM。