jQuery .on('click')在与:not()选择器一起使用时多次触发

时间:2013-03-28 07:33:31

标签: javascript jquery

早上好,

我在页面上有一组显示为列表的框,在这些框中可能有一些可以单击的链接。我希望框内的链接正常工作(即冒泡并执行默认操作,然后由DOM上的事件处理程序处理),但如果在其他任何地方单击该框,则应该由特定的附加到包含所有框的“列表”的事件处理程序。

简单的HTML表示

<div class="boxlist">
    <div class="box" data-boxid="1">
        Some text, and possibly a <a href="#">link</a> and another <a href="#">link</a>, and perhaps even a third <a href="#">link</a>.
    </div>
    <div class="box" data-boxid="2">
        Some more text, this time without a link.
    </div>
</div>

我认为应该有效的JavaScript。

$(function () {
    $('.boxlist').on('click', '.box :not(a)', function (e) {
        var boxid= $(this).closest('.box').data('boxid');
        console.log('open: ' + boxid);
    });
});

我的期望是上面的javascript应该处理所有不是来自标签的点击。但是,由于某些原因,当单击该框时(框本身或标记无关紧要),它会触发此事件X次,其中X是框列表中的标记总数。

所以我有两个问题: 1.我在做什么错误:not()选择器。 2.有更好的方法来处理这种情况吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

link使用jQuery:不是选择器实际上非常慢ex:http://jsperf.com/not-vs-notdasdsad/4而且使用event delegation会更好。因此,在这种情况下,您希望跟踪.boxlist上的每次点击,但检查节点类型以查看它是否为锚。这是一个例子。

$(function () {
    $('.boxlist').on('click', function(ev){
        if(ev.target.tagName != "A"){
            // handle box click code
            console.log('box click');
            return false;
        }
        // Otherwise allow event to bubble through.
    });
});

这是一个jsfiddle示例 http://jsfiddle.net/drXmA/

此外,他们的代码无法正常工作

.box :not(a)

应该是

.box:not(a)

以及这也不起作用的原因是因为.box不是一个锚标记,它有子元素作为锚标记,如果它们是一个不会执行回调的锚标记,它将永远不会找到名为.box的锚标记。将.box更改为锚标记将使代码无法执行,因为.box是一个锚,它只在.box:not(a)

时运行

答案 1 :(得分:0)

我猜你想要这样的东西:

$('.boxlist').on('click', '.box:not(a)', function (e) {
   var boxid = $(this).closest('.box').data('boxid');
   console.log('open: ' + boxid);
}).on('click', '.box a', function (e) {
   e.preventDefault().stopPropagation();
});

DEMO FIDDLE

我认为最好停止默认行为并停止将事件冒泡到其父级。 .on()链接至.box<a>,但e.preventDefault().stopPropagation();

停止默认行为和事件气泡