使用模式匹配时的jQuery选择器优先级

时间:2015-05-11 19:19:19

标签: javascript jquery javascript-events jquery-selectors event-handling

我正在创建一个实现一堆类似元素的表单。它们是自定义选择框,由<ul>创建。

其中一些元素在我希望处理mousedown事件的方式上略有不同。

我目前设置它的方式是,通过将_custom_select附加到元素类名称的末尾,就CSS而言,它将被视为这些特殊元素之一。

但是,当在类名称中找到字符串selections时(为了应用正确的样式,巧合地也会以_custom_select结尾)我想使用不同的mousedown事件处理程序

这是我的事件监听器设置的相关部分:

$('[class$="_custom_select"] li').mousedown(function(event){
    var opt= event.target;
    if(opt.className!='li_disabled' && event.which==1)
    {
        if(opt.className=='li_unselected'){
            opt.className= 'li_selected';
        }
        else{
            opt.className= 'li_unselected';
        }
        update_selections(opt.parentElement);       
    }
});

$('[class*="selections"]').mousedown(function(event){
    var opt=event.target;
    if(event.which==1){
        if(opt.className=='li_unselected'){
            opt.className= 'li_selected_2';
        }
        else{
            opt.className= 'li_unselected';
        }
    }
});

此代码有效,但请注意,在第二个绑定中,我必须将事件侦听器绑定到保存实际被单击的ul的{​​{1}}。({{1} }是类名与模式匹配的元素)然而,在第一个中,我可以将事件侦听器直接绑定到li中包含的ul元素。

如果我将第二个jQuery选择器更改为li,则事件侦听器永远不会绑定到相应的ul

导致此行为的原因是什么?

我知道我可以检查$('[class*="selections"] li')以确保事件从li冒出来,但这不是问题所在。

我原本以为它与优先级有关,并且侦听器没有被绑定,因为与第二个选择器匹配的event.target.tagName已经与第一个选择器匹配。

但是,在实现日志记录并查看DOM后,我确定当我将第二个选择器更改为:<li> 时, 事件监听器都不会绑定到与第二个选择器匹配的li

这是一个指向“工作版本”的JS小提琴的链接。如果您将$('[class*="selections"] li')添加到第二个选择器,然后尝试点击右侧框中的li,您将看到它们不再变为绿色。

的jsfiddle

https://jsfiddle.net/6sg6z33u/4/

1 个答案:

答案 0 :(得分:1)

好的,感谢发布jsFiddle。这很容易解决!

第二个li中的元素是动态添加的。使用.click()等快捷方法绑定到元素时,仅在最初绑定时绑定到页面上的元素

修复:使用.on()方法,这是每个jQuery基础的首选方法。此方法允许实时绑定,这意味着它将获取动态元素。

$('[class*="selections"]').on( 'mousedown', 'li', function(event) {
    var opt = event.target;
    if (event.which == 1) {
        if (opt.className == 'li_unselected') {
            opt.className = 'li_selected_2';
        } else {
            opt.className = 'li_unselected';
        }
    }
});