Javascript 文档不在元素jQuery中单击

Javascript 文档不在元素jQuery中单击,javascript,jquery,html,Javascript,Jquery,Html,使用jQuery,如何检测不在特定元素上的单击,并执行相应的操作 我有以下JavaScript $('#master').click(function() { $('#slave').toggle(); }); $(document).not('#master','#slave').click(function() { $('#slave').hide(); }); 我看不出我在逻辑上错在哪里。您可以看到一个活动示例,因为您绑定到文档上的单击事件,所以可以使用获取启动事件的元

使用jQuery,如何检测不在特定元素上的单击,并执行相应的操作

我有以下JavaScript

$('#master').click(function() {
    $('#slave').toggle();
});

$(document).not('#master','#slave').click(function() {
    $('#slave').hide();
});

我看不出我在逻辑上错在哪里。您可以看到一个活动示例

,因为您绑定到文档上的
单击事件,所以可以使用获取启动事件的元素:

$(document).click(function(event) {
    if (!$(event.target).is("#master, #slave")) {
        $("#slave").hide();
    }
});
编辑:正如Mattias在其评论中正确指出的那样,上述代码将无法识别来自
#master
#slave
后代的点击事件(如果有)。在这种情况下,您可以使用检查事件的目标:

$(document).click(function(event) {
    if (!$(event.target).closest("#master, #slave").length) {
        $("#slave").hide();
    }
});

此代码是否符合您的要求?(不完全确定我是否理解正确)


另一种想法是,它可能不起作用,因为您的浏览器可能无法以100%的高度渲染身体;试着调整你的基本css来固定身体的高度,然后再考虑其他一些问题

:防止事件在DOM树中冒泡,防止任何父处理程序收到事件通知

因此,如果将首次单击代码更改为以下代码:

$('#master').click(function(e) {
    e.stopPropagation();
    $('#slave').toggle();
});
然后您也可以更改第二个的呼号:

$("body, body *").not('#master, #slave').click(function(e) {
    $('#slave').hide();
});

这应该包括在内。试试看!或者参见jQuery长期以来在本机上支持的事件委派。困难在于创建适当的选择器。最初使用,但最近应使用的委托形式

事件委派的目的是侦听子元素上的事件,并调用这些元素上的绑定事件处理程序,就像它们已绑定到子元素而不是父元素一样。这意味着,不是将处理程序绑定到DOM中的每个元素,而是将处理程序绑定到初始选择中的每个元素(
document
是单个元素)。这还提供了一种简单的方法,可以使用单个选择器绑定到不断变化的元素集,因为新元素将把它们的事件传播到
文档
,无论它们在绑定初始事件处理程序时是否存在:

$(document).on('click', '*:not(#master, #master *, #slave, #slave *)', function (e) {
    //this will reference the clicked element
});

此外,请注意,我不仅说元素不能是
#master
#slave
,它们也不能是
#master
#slave
的子元素。

    $(document).on('click',function(event) {
        if (!$(event.target).closest("#selector").length) {
            if ($('#selector').is(":visible"))
                $('#selector').slideUp();
        }
    });
我会把它作为一个评论发布,但我没有足够的声誉

$('.clickable-row').on("click",function(){
  window.location = $(this).data('href');
  return false;
});
$("td > a").on("click",function(e){
  e.stopPropagation();
});


将单击处理程序的实例绑定到每个DOM元素(两个除外)会对性能造成严重影响。版本不起作用的原因是,您正在测试
文档
元素是否没有
作为其ID。这总是正确的(IIRC
文档
不能有ID),因此处理程序绑定到
文档
,每次单击都会导致
从属
被隐藏。然后,由于事件传播,来自
#主
单击
事件将冒泡到
文档
中,它将隐藏
#从属
,即使
#主
刚刚切换了它。您需要测试
event.target
来实现此功能。将事件处理程序绑定到其他所有元素不是一个好主意。Frédéric Hamidi的解决方案更好。这是一个糟糕的解决方案。您将第二个处理程序分别绑定到DOM中的每个元素。这不仅效率极低,甚至无法使用动态插入ed元素后来添加到DOM中。Frédéric的解决方案更加优雅,而且(更重要的是)适用于任何情况。我从未说过这是最好的解决方案,也没有“可怕”。我只是向他展示了如何实现他试图实现的目标。这么多“教授”在这里.lmao如果
#master
#slave
有子元素,则需要使用
最接近的
而不是
is
,以使其对这些子元素起作用。这是一个很差的替代品,jQuery中已经实现了它。@zzzzBov,不是真的,这里的目标是将所有
click
事件委托给文档t和特殊情况下的两个元素及其后代。你确定你可以用
委托()
(或者更确切地说是
on()
,它在最近的版本中取代了它)实现同样的效果吗?@FrédéricHamidi,很容易,看到我的答案。非常有趣。我通常避免在CSS中使用
*
选择器(级联在大多数情况下都是足够的)在jQuery中(匹配整个子树可能会很昂贵),但我同意这应该至少和现代浏览器上的
event.target
组合到
closest()
一样有效。现在我对性能很好奇,也许我会在我丰富的空闲时间里建立一个基准。干杯:)
$('.clickable-row').on("click",function(){
  window.location = $(this).data('href');
  return false;
});
$("td > a").on("click",function(e){
  e.stopPropagation();
});
jQuery(document).ready(function($) {
    $('.clickable-row').on("click",function(){
      window.location = $(this).data('href');
      return false;
    });
    $("td > a").on("click",function(e){
        e.stopPropagation();
    });
});