由于浏览器之间的目标元素存在差异,事件委托失败

发布于 2024-11-08 17:04:42 字数 1025 浏览 0 评论 0原文

这是 DOM 的简化摘录:

<td>
    <button value="11" class="expand ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only" role="button" title="">
        <span class="ui-button-icon-primary ui-icon ui-icon-plus"></span>
        <span class="ui-button-text"></span>
    </button>
</td>

对表中的每一行 (~500) 重复此操作,并且表的 ID 为“eventTable”

这是按钮实例化 (jQueryUI):

$('.expand').each(function(){
    $(this).button({
        text: false,
        icons: {
            primary: "ui-icon-plus"
        }
    });
});

这是表上事件委托的一部分#eventTable

$('#eventTable').click(function(e){
    if($(e.target).is('.expand'){
        // ...

现在,在 Firefox 3.6.x、IE7,8 中,此方法可以工作并进入 if 语句。然而,在 Safari 和 Chrome 中,e.target 代表第一个 span,而不是周围的按钮

为什么会发生这种情况?我可以克服它,但我希望得到一个解释,这样我以后就不会在不同的场景中遇到同样的问题。为什么Webkit是对的而Trident/Gecko是错的?是什么造成了这种差异?

This is a simplified excerpt from the DOM:

<td>
    <button value="11" class="expand ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only" role="button" title="">
        <span class="ui-button-icon-primary ui-icon ui-icon-plus"></span>
        <span class="ui-button-text"></span>
    </button>
</td>

This is repeated for every row in the table (~500), and the table has an ID of 'eventTable'

Here's the button instantiation (jQueryUI):

$('.expand').each(function(){
    $(this).button({
        text: false,
        icons: {
            primary: "ui-icon-plus"
        }
    });
});

Here's a part of the event delegation on table #eventTable

$('#eventTable').click(function(e){
    if($(e.target).is('.expand'){
        // ...

Now, in Firefox 3.6.x, IE7,8, this works and steps into the if statement. In Safari and Chrome, however, e.target represents the first span instead of the surrounding button.

Why is this happening? I can work past it, but I would love an explanation so I don't run into the same problem later in a different scenario. Why is Webkit right and Trident/Gecko wrong? What caused the difference?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

逆流 2024-11-15 17:04:42

发布我的评论作为答案。

如果您只是担心不要在 DOM 上获得大量 click 处理程序引用,我建议您使用 。而是用 delegate() 来代替。它仅将一个处理程序“绑定”到上下文,并检查事件目标是否与您提供的选择器匹配,如果匹配则触发处理程序。

像这样的东西

$('#eventTable').delegate('click', '.expand', function() {
    // click on the .expand element/s
});

就足够了。

Posting my comment as an answer.

If you're just wary not to get a ton of click handler references on your DOM, I'd suggest you use .delegate() instead. It "binds" only one handler onto a context, and checks if the event target matches a selector you provide, and fires off the handler if it does.

Something like

$('#eventTable').delegate('click', '.expand', function() {
    // click on the .expand element/s
});

should suffice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文