jQuery 使用模式匹配时的选择器优先级
jQuery selector precedence when using pattern matching
我正在创建一个实现了一堆相似元素的表单。它们是自定义 select 框,由 <ul>
创建。
其中一些元素与我希望处理 mousedown
事件的方式略有不同。
我目前的设置方式是,通过将 _custom_select
附加到元素 class 名称的末尾,它将被视为这些特殊元素之一 CSS 关注。
但是,当在 class 名称中找到字符串 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
,该 ul
包含实际被点击的 li
。(ul
是 class 名称与模式匹配的元素)但是在第一个中,我可以将事件侦听器直接绑定到 ul
中包含的 li
元素。
如果我将第二个 jQuery selector 更改为 $('[class*="selections"] li')
,则事件侦听器永远不会绑定到相应的 li
。
是什么导致了这种行为?
我知道我可以检查 event.target.tagName
以确保事件从 <li>
冒泡,但这不是问题所在。
我最初认为它与优先级有关,并且听众没有被绑定,因为 li
本来可以匹配第二个 select 或已经匹配第一个 select或者。
但是,在实施日志记录并查看 DOM 之后,我确定当我将第二个 selector 更改为:$('[class*="selections"] li')
事件侦听器都未绑定到与第二个 selector 匹配的 li
。
这里是一个link到一个JSfiddle的'working version'。如果您将 ' li'
添加到第二个 selector 然后尝试单击右侧框中的 <li>
,您将看到它们不再变为绿色。
jsFiddle
好的,感谢您发布 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';
}
}
});
我正在创建一个实现了一堆相似元素的表单。它们是自定义 select 框,由 <ul>
创建。
其中一些元素与我希望处理 mousedown
事件的方式略有不同。
我目前的设置方式是,通过将 _custom_select
附加到元素 class 名称的末尾,它将被视为这些特殊元素之一 CSS 关注。
但是,当在 class 名称中找到字符串 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
,该 ul
包含实际被点击的 li
。(ul
是 class 名称与模式匹配的元素)但是在第一个中,我可以将事件侦听器直接绑定到 ul
中包含的 li
元素。
如果我将第二个 jQuery selector 更改为 $('[class*="selections"] li')
,则事件侦听器永远不会绑定到相应的 li
。
是什么导致了这种行为?
我知道我可以检查 event.target.tagName
以确保事件从 <li>
冒泡,但这不是问题所在。
我最初认为它与优先级有关,并且听众没有被绑定,因为 li
本来可以匹配第二个 select 或已经匹配第一个 select或者。
但是,在实施日志记录并查看 DOM 之后,我确定当我将第二个 selector 更改为:$('[class*="selections"] li')
事件侦听器都未绑定到与第二个 selector 匹配的 li
。
这里是一个link到一个JSfiddle的'working version'。如果您将 ' li'
添加到第二个 selector 然后尝试单击右侧框中的 <li>
,您将看到它们不再变为绿色。
jsFiddle
好的,感谢您发布 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';
}
}
});