当用户在其外部单击时,使用jQuery隐藏DIV

Sco*_* UX 939 html jquery styling hide

我正在使用此代码:

$('body').click(function() {
   $('.form_wrapper').hide();
});

$('.form_wrapper').click(function(event){
   event.stopPropagation();
});
Run Code Online (Sandbox Code Playgroud)

这个HTML:

<div class="form_wrapper">
   <a class="agree" href="javascript:;">I Agree</a>
   <a class="disagree" href="javascript:;">Disagree</a>
</div>
Run Code Online (Sandbox Code Playgroud)

问题是我在DIV内部有链接,当它们点击时它们不再有效.

小智 2431

有同样的问题,想出了这个简单的解决方案.它甚至可以递归工作:

$(document).mouseup(function(e) 
{
    var container = $("YOUR CONTAINER SELECTOR");

    // if the target of the click isn't the container nor a descendant of the container
    if (!container.is(e.target) && container.has(e.target).length === 0) 
    {
        container.hide();
    }
});
Run Code Online (Sandbox Code Playgroud)

  • **记住**使用[`$("你的容器选择器").解绑('click',clickDocument);`(http://api.jquery.com/unbind/)就在*`.hide旁边( )`*.因此`document`不会继续听取点击. (79认同)
  • 只需将它放在我的项目中,但稍作调整,使用一系列元素一次循环遍历它们.http://jsfiddle.net/LCB5W/ (18认同)
  • 对于最佳实践,我写了`$(document).on("mouseup.hideDocClick",function(){...});`在打开容器的函数中,``$(document).off(' .hideDocClick');`on hide function.使用[namespaces](http://api.jquery.com/on/#event-names)我没有删除附加到文档的其他可能的`mouseup`监听器. (11认同)
  • 我需要使用此事件隐藏容器一次,使用时应该销毁此回调.为此,我在使用bind("click.namespace")的click事件上使用了命名空间,当事件发生时,我调用unbind("click.namespace").最后,我使用$(e.target).closest(".container").length来识别容器...所以,我没有使用这个答案的任何技巧:D (6认同)
  • @mpelzsherman很多人评论说这个代码片段适用于触摸设备但是由于帖子已被编辑,这些评论有些消失了.TBH我不知道我是否因为某个特定原因使用了"mouseup",但如果它也适用于"click",我认为没有理由不使用"click". (5认同)
  • 此解决方案没有考虑到事件应该只抛出一次. (4认同)
  • 2个问题:1)这与触摸设备有关吗?2)有没有理由使用mouseup与click? (3认同)
  • @brasofilo这对我不起作用.获取ReferenceError:未定义clickDocument.因为没有处理程序.处理程序应该怎么样?! (3认同)
  • 也许一个小补充:`$(document).on('mouseup touchend focusin', function functionName(e) {...});`。应该适用于桌面、触摸设备,并且“focusin”如果使用正确,应该在跳出 div 区域以实现可访问性行为时处理键盘导航(例如,在跳出时关闭容器)。条件的一个不太漂亮的版本可能是:`if ($(e.target).parents(".parent-div-class").length === 0)`。尽管这个答案提供了更好的检查! (3认同)
  • 我只是想添加之前关于获取数组和循环的评论 - 你可以这样做: `let container = $(".thing1, .thing2, .thing3, .thing4");` 而不必更改其余部分的代码。 (2认同)

Mak*_*leh 200

你最好选择这样的东西:

var mouse_is_inside = false;

$(document).ready(function()
{
    $('.form_content').hover(function(){ 
        mouse_is_inside=true; 
    }, function(){ 
        mouse_is_inside=false; 
    });

    $("body").mouseup(function(){ 
        if(! mouse_is_inside) $('.form_wrapper').hide();
    });
});
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于平板电脑,因为你无法悬停! (89认同)
  • 我不认为这是一个很好的解决方案,因为它让人们认为填充window-object(=使用全局变量)是可以的. (4认同)
  • @ prc322如果您甚至不知道如何更改变量的范围,那么您是对的,这个解决方案对您不利......而且JavaScript也不是.如果你只是从Stack Overflow复制和粘贴代码,那么你可能会遇到很多问题,而不是覆盖窗口对象中的某些东西. (3认同)
  • 只是为了在 @prc322 所说的基础上添加一些内容,您可以使用匿名函数包装代码并立即调用它。`(function() { // ... code })();` 我不记得这个模式的名字了,但它非常有用!所有声明的变量都将驻留在函数内,不会污染全局命名空间。 (2认同)

Cas*_*ase 80

此代码检测页面上的任何单击事件,然后#CONTAINER当且仅当单击的#CONTAINER元素既不是元素也不是其后代之一时隐藏元素.

$(document).on('click', function (e) {
    if ($(e.target).closest("#CONTAINER").length === 0) {
        $("#CONTAINER").hide();
    }
});
Run Code Online (Sandbox Code Playgroud)


Dav*_*res 73

您可能希望检查为正文触发的单击事件的目标,而不是依赖于stopPropagation.

就像是:

$("body").click
(
  function(e)
  {
    if(e.target.className !== "form_wrapper")
    {
      $(".form_wrapper").hide();
    }
  }
);
Run Code Online (Sandbox Code Playgroud)

此外,主体元素可以不包括浏览器中所示的整个视觉空间.如果您注意到您的点击未注册,则可能需要添加HTML元素的点击处理程序.

  • -1.当您单击其中一个子项时,这会隐藏`form_wrapper`,这不是所需的行为.请改用prc322的答案. (2认同)

Sal*_*lim 35

现场演示

检查点击区域不在目标元素中或在其子元素中

$(document).click(function (e) {
    if ($(e.target).parents(".dropdown").length === 0) {
        $(".dropdown").hide();
    }
});
Run Code Online (Sandbox Code Playgroud)

更新:

jQuery停止传播是最好的解决方案

现场演示

$(".button").click(function(e){
    $(".dropdown").show();
     e.stopPropagation();
});

$(".dropdown").click(function(e){
    e.stopPropagation();
});

$(document).click(function(){
    $(".dropdown").hide();
});
Run Code Online (Sandbox Code Playgroud)


med*_*iev 19

$(document).click(function(event) {
    if ( !$(event.target).hasClass('form_wrapper')) {
         $(".form_wrapper").hide();
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 不要检查目标是否有类,请尝试:if($(event.target).closest('.form_wrapper).get(0)== null){$(".form_wrapper").hide(); 这将确保点击div内部的内容不会隐藏div. (11认同)
  • 嗯......如果我点击div中的内容,整个div会因某种原因消失. (2认同)

ben*_*vds 17

将解决方案更新为:

  • 改用mouseenter和mouseleave
  • 悬停使用实时事件绑定

var mouseOverActiveElement = false;

$('.active').live('mouseenter', function(){
    mouseOverActiveElement = true; 
}).live('mouseleave', function(){ 
    mouseOverActiveElement = false; 
});
$("html").click(function(){ 
    if (!mouseOverActiveElement) {
        console.log('clicked outside active element');
    }
});
Run Code Online (Sandbox Code Playgroud)

  • `.live` 现在*已弃用*;改用`.on`。 (2认同)

Mar*_*cka 13

最流行的答案是没有jQuery的解决方案:

document.addEventListener('mouseup', function (e) {
    var container = document.getElementById('your container ID');

    if (!container.contains(e.target)) {
        container.style.display = 'none';
    }
}.bind(this));
Run Code Online (Sandbox Code Playgroud)

MDN:https://developer.mozilla.org/en/docs/Web/API/Node/contains


Rok*_*jan 9

具有ESC功能的现场演示

适用于桌面和移动设备

var notH = 1,
    $pop = $('.form_wrapper').hover(function(){ notH^=1; });

$(document).on('mousedown keydown', function( e ){
  if(notH||e.which==27) $pop.hide();
});
Run Code Online (Sandbox Code Playgroud)

如果在某些情况下,您需要确保在单击文档时确实可以看到元素: if($pop.is(':visible') && (notH||e.which==27)) $pop.hide();


小智 7

不会像这样的工作吗?

$("body *").not(".form_wrapper").click(function() {

});
Run Code Online (Sandbox Code Playgroud)

要么

$("body *:not(.form_wrapper)").click(function() {

});
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是不正确的.像这里的许多答案一样,当你点击它的子句(以及其他问题)时,这将隐藏`.form_wrapper`. (4认同)

zak*_*zak 7

这么多答案,必须是添加一个的通行权......我没有看到当前(jQuery 3.1.1)的答案 - 所以:

$(function() {
    $('body').on('mouseup', function() {
        $('#your-selector').hide();
    });
});
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以设置tabindex为父级<div>并监听focusout事件,而不是监听DOM来隐藏一个特定元素,而无需每次单击。

设置tabindex将确保在blur上触发事件<div>(通常不会触发)。

因此,您的HTML如下所示:

<div class="form_wrapper" tabindex="0">
    <a class="agree" href="javascript:;">I Agree</a>
    <a class="disagree" href="javascript:;">Disagree</a>
</div>
Run Code Online (Sandbox Code Playgroud)

还有你的JS:

$('.form_wrapper').on('focusout', function(event){
    $('.form_wrapper').hide();
});
Run Code Online (Sandbox Code Playgroud)


小智 5

甚至是运动鞋:

$("html").click(function(){ 
    $(".wrapper:visible").hide();
});
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是不正确的。无论您在页面上的什么位置,这都将隐藏.wrapper,这不是要求的。 (4认同)

小智 5

如果您在使用 ios 时遇到问题,则 mouseup 无法在 Apple 设备上运行。

jquery 中的 mousedown /mouseup 是否适用于 ipad?

我用这个:

$(document).bind('touchend', function(e) {
        var container = $("YOURCONTAINER");

          if (container.has(e.target).length === 0)
          {
              container.hide();
          }
      });
Run Code Online (Sandbox Code Playgroud)


djv*_*djv 5

这是我在另一个线程上找到的jsfiddle,它也可以使用esc键:http : //jsfiddle.net/S5ftb/404

    var button = $('#open')[0]
    var el     = $('#test')[0]

    $(button).on('click', function(e) {
      $(el).show()
      e.stopPropagation()
    })

    $(document).on('click', function(e) {
      if ($(e.target).closest(el).length === 0) {
        $(el).hide()
      }
    })

    $(document).on('keydown', function(e) {
      if (e.keyCode === 27) {
        $(el).hide()
      }
    })
Run Code Online (Sandbox Code Playgroud)


Cod*_*Spy 5

对于IPAD和IPHONE等触控设备,我们可以使用以下代码

$(document).on('touchstart', function (event) {
var container = $("YOUR CONTAINER SELECTOR");

if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
    {
        container.hide();
    }
});
Run Code Online (Sandbox Code Playgroud)


小智 5

(只是添加到 prc322 的答案。)

在我的情况下,我使用此代码隐藏当用户单击适当的选项卡时出现的导航菜单。我发现添加一个额外条件很有用,即容器外点击的目标不是链接。

$(document).mouseup(function (e)
{
    var container = $("YOUR CONTAINER SELECTOR");

    if (!$("a").is(e.target) // if the target of the click isn't a link ...
        && !container.is(e.target) // ... or the container ...
        && container.has(e.target).length === 0) // ... or a descendant of the container
    {
        container.hide();
    }
});
Run Code Online (Sandbox Code Playgroud)

这是因为我网站上的一些链接向页面添加了新内容。如果在导航菜单消失的同时添加此新内容,则可能会使用户迷失方向。


Wis*_*Man 5

基于prc322的出色回答。

function hideContainerOnMouseClickOut(selector, callback) {
  var args = Array.prototype.slice.call(arguments); // Save/convert arguments to array since we won't be able to access these within .on()
  $(document).on("mouseup.clickOFF touchend.clickOFF", function (e) {
    var container = $(selector);

    if (!container.is(e.target) // if the target of the click isn't the container...
        && container.has(e.target).length === 0) // ... nor a descendant of the container
    {
      container.hide();
      $(document).off("mouseup.clickOFF touchend.clickOFF");
      if (callback) callback.apply(this, args);
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

这增加了几件事...

  1. 放在带有“无限” args回调的函数中
  2. 添加了对jquery的.off()的调用以及事件名称空间,以在事件运行后将其与文档解除绑定。
  3. 随附的用于移动功能的触摸端

我希望这可以帮助别人!