jQuery’on’没有在动态生成的模态弹出窗口中注册
我的印象是,jQuery的on
事件处理程序意味着能够“监听”动态创建的元素,并且它应该取代live
的行为。 但是,我所经历的是使用on
不捕获click事件,而使用live
是成功的!
我的情况的棘手方面是我不仅动态创建内容,而且我通过AJAX .get()
调用,并将结果HTML插入模态.dialog()
jQueryUI弹出窗口。
这是我试图完成的简化版本(包含在$(document).ready(...)
):
$.get("getUserDataAjax.php", queryString, function(formToDisplay) { $("#dialog").dialog({ autoOpen: true, modal: true, buttons... }).html(formToDisplay); }); $(".classThatExistsInFormToDisplay").on("click", function() { alert("This doesn't get called"); });
从我的文档中我发现了这是我接近编写我的on
事件的方式:
$("p").on("click", function(){ alert( $(this).text() ); });
但是,出于某种原因, live
会像我期望的那样工作 – 而on
则让我失望。
这不是“如何使其工作”的问题,因为我发现如果我在function(formToDisplay)
回调中声明它将成功(捕获点击)。
我的问题是:在模态弹出窗口中找不到我动态创建的元素有什么问题? 我的jQuery实例是jquery-1.7.2。 jQueryUI是1.8.21。
这里有两个jsFiddles来解决这个问题。 单击两个实例中的单词“Test”以查看不同的行为。 代码的唯一区别是替换为live
。
live
捕获点击的位置。
没有捕获点击的地方(点击’测试 – 点击我’看看什么都没发生)。
我意识到我可能只是不恰当地使用或者要求它做一些不打算但我想知道它为什么不起作用的东西(但如果你有一些非常聪明的东西,请随意分享)。 谢谢你的智慧!
更新/解答/解决方案:
根据用户’undefined’,不同之处在于on
不是从document
对象的顶部一直委托,而live
是/。
正如Claudio所提到的, on
document的部分内容引用了动态创建的元素,并且您在查询的$("")
部分中包含的内容需要在运行时存在 。
这是我的新解决方案: on
我的modal dialogon
捕获单击事件,虽然它在运行时创建事件时没有任何内容,但是能够找到我的内容和元素,后面会生成特殊的类。
$("#dialog").on("click", ".classThatExistsInFormToDisplay", function() { ... //(success! Event captured) });
非常感谢!
live
从文档对象委托事件,但是如果要使用on
方法委托事件,则应该委托事件来自元素或document
对象的静态父项之一:
$(document).on("click", ".clickHandle", function() { alert("Content clicked"); });
问题是您附加事件的元素必须存在。
你必须像这样使用来捕获动态创建的p
标签的点击
$("#existingContainerId").on("click", "p", function(){ alert( $(this).text() ); });
如果您没有相关的现有容器可以使用,您可以使用$("body")
或$(document)
如果省略selector或为null,则事件处理程序称为直接或直接绑定。 每次在所选元素上发生事件时都会调用该处理程序,无论它是直接发生在元素上还是来自后代(内部)元素的气泡。
提供选择器时,事件处理程序称为委托。 当事件直接发生在绑定元素上时,不会调用处理程序,但仅适用于与选择器匹配的后代(内部元素)。 jQuery将事件从事件目标起泡到附加处理程序的元素(即最里面到最外层的元素),并为匹配选择器的路径上的任何元素运行处理程序。
事件处理程序仅绑定到当前选定的元素; 它们必须存在于您的代码调用.on()时页面上 。 要确保元素存在且可以选择,请在文档就绪处理程序内对页面上HTML标记中的元素执行事件绑定。 如果将新HTML注入页面,请在将新HTML放入页面后选择元素并附加事件处理程序。 或者,使用委托事件来附加事件处理程序,如下所述
有关更多详细信息,请查看此处的 直接和委派事件部分