使用jQuery on()绑定click事件无法在通过Ajax调用注入的HTML上触发

7

我有一个局部视图,通过dataType为html的Ajax调用返回 - 在这个html中有一个带有id的锚点标签,我正在使用jQuery的.on() API和1.7.1版本的框架来连接点击事件。

为了简洁起见,假设局部视图如下:

<div id="container" class="modal-dialog">
    <h1>Heading</h1>
    <a id="thelink" href="#">
        <img src="<%:Url.Content("~/Path/To/Image.jpg")%>" /></a>
</div>

通过标准的$.ajax POST请求到MVC控制器操作,该操作返回上述内容作为部分视图结果,我截取并放置在模态对话框中。

我尝试连接的事件代码如下:

$(function () {
    $("#thelink").on("click", function (e) {
        e.preventDefault();
        $("#jquery-ui-dialog-box").dialog("close");
    });
});

现在,如果我将on()切换为live() - 一切都按预期工作。但是使用上面的代码在IE8(IE8标准模式)中,事件不会触发-断点没有命中,jQuery UI模态框不会像上面的示例那样关闭。然而,通过live()调用,所有内容都按预期工作。
这是我第一次也是唯一一次看到on()和已弃用或“卷起来”的事件绑定API(delegate、live、bind)之间行为差异的情况。
我没有使用live()delegate()出现问题,但希望了解为什么会发生这种情况,如果可能的话!
问候 SB
1个回答

9

$(foo).live(type, handler) 相当于 $(document).on(type, foo, handler),因此请尝试使用以下语句代替:

$(function () {
    $(document).on("click", '#thelink', function (e) {
        e.preventDefault();
        $("#jquery-ui-dialog-box").dialog("close");
    });
});
live() 的签名很令人困惑; 实际上,您并没有将处理程序绑定到选定的元素,而是将其绑定到 document 元素,该元素侦听要在与给定选择器匹配的元素上触发的事件 ( jQuery .live() 是如何工作的? )。 $(foo).live(type, handler) 等效于 $(document).delegate(foo, type, handler)
供以后参考,$(foo).delegate(selector, type, handler) 可以通过交换第一个和第二个参数来转换为 on(); on() 首先期望事件类型,然后是(可选的)选择器。

+1 - 完美 - 我盲目地假设(错误地)事件绑定的“签名”将是相同的,但实际上并不是。集成您的建议对我的实际代码有效。干杯。 - SpaceBison
@Matt 如果应用程序有许多屏幕和导航,同时我们将许多单击处理程序绑定到 $(document),那么性能可能会受到影响。不是吗? - Samba
@Samba:虽然正确,但在你注意到任何性能下降之前,你要考虑很多、很多、很多。不要忘记你可以使用delegate()on()来附加到更接近目标元素的元素,而不是附加到document - Matt
@Matt 感谢您的回复。但是,使用$(container).on方式的问题在于 - 如果容器是通过Ajax响应动态添加到DOM中的,则无法使用该方法,因此不得不使用document。 - Samba
@Matt 如果你能评论一下我考虑采取的方法,将会是非常有帮助的。https://dev59.com/-WjWa4cB1Zd3GeqPpli5 - Samba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接