我有列表,并且可以通过mousedown事件选择列表的元素(一次一个,或者在 Ctrl 键的帮助下更多)。我想通过mouseup在文档中的任何位置取消选择所选元素,但这些列表元素。 我试过这个但是不起作用:
$("body").delegate("body:not(.selected_li)", "mouseup", function(event) { .......
当我单击文档上的任何位置(但选择的li
)时,鼠标事件不会发生。
请帮助我。
谢谢。
答案 0 :(得分:3)
您需要将事件侦听器绑定到正文,并检查单击的元素以查看它是.selected_li
,还是其后代之一:
$('body').mouseup(function(e) {
if ($(e.target).closest('.selected_li').length == 0) {
// de-select
}
});
这里的真正诀窍是使用.closest(".selected_li")
,因为它确保包含你在“.selected_li”的孩子身上的实例。
如果您的列表看起来像这样,那么使用.is(".selected_li")
将无效:
<ul>
<li>Item 1</li>
<li class="selected_li"><i>Item 2</i></li>
<li>Item 3</li>
</ul>
如果您在第2项时释放鼠标按钮,则event.target
将是<i>
元素,而不是<li>
,因此.is(".selected_li")
将返回false。因此,我们必须通过使用".selected_li"
进行搜索并查看我们是否匹配来查看事件目标或其任何祖先是否为.closest()
。
修改:在这里使用.delegate()
并不是一个好主意。这会将事件处理程序绑定到<body>
的每个后代元素,这是非常多余的,因为事件总是会冒泡到<body>
并且您只需要执行一次。但是, 是可能的,但你需要确保排除足够的内容 - 你需要排除“.selected_li”及其所有后代及其所有后代:
$("body").delegate(":not(.selected_li, .selected_li *, :has(.selected_li))", "mouseup", function(e) {
// de-select
});
但是,这将导致每次点击多次调用事件处理程序。如果在以下段落中释放鼠标按钮,则将执行5次事件处理程序。适用于<em>
,<p>
,<div class="section">
,<div id="content">
,<div id="wrapper">
的每一次。
<body>
<div id="wrapper">
<div id="content">
<div class="section">
<p><em>Here is a paragraph</em></p>
</div>
</div>
</div>
</body>
因此,只需将一次绑定到body,以便每次单击只调用一次事件处理程序。
答案 1 :(得分:0)
这应该做你需要的......
$('body').mouseup(function(e){
if ( !$(e.target).is('.selected_li') ) {
// do the de-selection here..
}
});
演示
答案 2 :(得分:0)
您无法从body
委托给body
。 body
是你的根元素,所以我认为你想要的是:
$("body").delegate("li:not(.selected_li)", "mouseup", function(event) {
/* */
});
答案 3 :(得分:0)