我有列表,可以通过 mousedown 事件选择列表中的元素(一次一个,或借助 Ctrl 键选择多个元素)。我想通过在文档中除这些列表元素之外的任何位置上单击鼠标来取消选择所选元素。 我尝试了这个但不起作用:
$("body").delegate("body:not(.selected_li)", "mouseup", function(event) { .......
当我单击文档上的任意位置(但选定的 li
)时,mouseup 事件不会发生。
请帮助我。
谢谢。
最佳答案
您需要将事件监听器绑定(bind)到正文,并检查单击的元素以查看它是否是 .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()
这不是一个好主意。这会将事件处理程序绑定(bind)到 <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>
因此,只需将一次绑定(bind)到主体,以便每次点击仅调用一次事件处理程序。
关于javascript - JQuery关于mouseup事件的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6700293/