jQuery点击元素事件关闭

44
我有一个浮动的div,当它被显示时,我希望在用户点击div以外的区域时将其隐藏。类似于.hover()函数在悬停在元素上时的回调,只不过我想使用点击事件。
我尝试在body上设置点击事件来隐藏div,但结果出乎意料。
有人有想法如何轻松实现这个功能吗?

5
请详细说明“导致了意外的结果”。 - Crescent Fresh
15个回答

86

如果你想在页面的其他地方点击时清除div,可以这样做:

$('body').click(function(event) {
    if (!$(event.target).closest('#myDiv').length) {
        $('#myDiv').hide();
    };
});

这是我当前情况下唯一有效的解决方案。谢谢! - Dom
5
.closest 方法返回一个 jQuery 对象。如果没有找到任何元素,则返回一个空的 jQuery 对象。 .length 可以用来判断是否找到了元素,因为 0==false 而 1==true,而一个 jQuery 对象无论是否为空都是"true". - David Bennett
这太棒了,我花了2-3天时间寻找答案。这个可行!简短的问题,每次点击调用它会如何影响性能? - netwire
这个很好用。添加了这个以考虑到触发器。(!$(event.target).closest('#myDiv').length && !$(event.target).closest('#trigger').length) - noWayhome

19

另一个可能更简单的选择是在浮动 DIV 和页面其他部分之间添加一个透明的 div。

透明 DIV 上的简单点击事件可以处理隐藏,避免了您遇到的点击事件问题。


好主意。我以前在不同的情况下做过类似的事情。感谢你让我注意到这个。 - Nic Hubbard
欢迎您,感谢您接受了我的答案。我差点没有发帖,因为我不太清楚您正在设计什么,而且我认为这个选项可能行不通 - 但有时候外部人员的观点是解决问题的最佳方式。祝你好运! - PhillFox
4
这个比DavidB的答案简单在哪里? - JPot
1
我称它为更简单的解决方案是因为Nic在使用body的click事件时报告了意外结果。我的解决方案可能没有DavidB的那么优雅,因为我不像他那样熟练掌握JQuery,但仅通过等待隐藏DIV上的点击事件即可完成任务。 我只是提供另一个他可以考虑的选项... - PhillFox
4
刚刚通过谷歌无意间发现了这篇文章,想留下我的评论。PhillFox方案的优点是透明的层可以阻挡任何实际的链接或按钮点击。有时如果出现一个漂浮的层,用户会随意地点击层之外的区域来让它消失。透明的层可以防止误点,而DavidB的方案则不能。 - CaptSaltyJack
PhillFox - 此外,这种解决方案意味着您的脚本不会在每次单击事件上运行。可能是一个小的效率问题,但我绝对认为它更加清晰。除了@CaptSaltyJack上面提到的原因(防止用户意外点击链接),我认为这是一个更好的解决方案。 - dazbradbury

11
如果你正在使用 jQuery,你可以使用像这样的选择器:
$("*:not(#myDiv)").live("click", function(){
    $("#myDiv").hide();
});

2
抱歉 - 应该是这样的:$("*:not(#myTrigger)").live("click", function(){ $("#myDiv").hide(); }); - Kelly
谁投了反对票,为什么?那对我来说完美地运作了。谢谢! - HandiworkNYC.com
1
这不会将一个点击监听器附加到每个不是#myDiv的元素上吗?似乎比简单地使用$('body')增加了更大的浏览器内存负担。 - Dan Gravell

10

1
叹气 有人能解释一下这个踩的原因吗?(或者所有这些踩?) - annakata
“blur”事件仅适用于表单元素,提问者可能正在寻找类似于非表单元素的功能。 - Tobias Baaz
2
这绝对不是真的 - http://www.quirksmode.org/dom/events/blurfocus.html - annakata
1
这实际上非常优雅 - 谢谢annakata。 $(".modal_div").live("blur", function(){$(this).hide();}); - ndorfin
2
很高兴对某人有所帮助。缺乏涉及模糊的答案让我感到困惑。 - annakata

9

最好的方法是:

$(document).bind('click', function(e) {
var $clicked = $(e.target);
if (!$clicked.parents().hasClass("divtohide")) { $(".divtohide").hide(); }
});
这段代码可以在点击页面时隐藏具有“divtohide”类的元素。

1
这是一个漂亮优雅的选择 :) 如果你正在使用类的话 - Prof

2

这对我起作用了,

var mouseOver = false;
$("#divToHide").mouseover(function(){mouseOver=true;});
$("#divToHide").mouseout(function(){mouseOver=false;});
$("body").click(function(){
      if(mouseOver == false) {
           $("#divToHide").hide();
      }
});

1

例如,您单击链接元素以显示 div 菜单,只需将 blur 函数绑定到链接元素即可隐藏 div 菜单。

$('a#displaymenu').click(function(){
   $("#divName").toggle();
}).blur(function() {$("#divName").hide()})

1
这是一个处理点击事件的函数,我将弹出窗口的选择器和jQuery元素传递给它。可能更适合作为jQuery插件,但这已经足够简单了。
clickOut = function(selector, element) {
 var hide = function(event) {
  // Hide search options if clicked out
  if (!$(event.originalEvent.target).parents(selector).size())
   $(element).hide();
  else
   $(document).one("click",hide);
 };

 $(document).one("click", hide);
};

所以,如果您有一个弹出元素,例如<div class='popup'>test</div>,您可以使用我的函数,如下所示:clickOut("div.popup", $("div.popup"));


1
     $('body').click(function (event) {        
if ($("#divID").is(':visible')) {
            $('#divID').slideUp();
        }
});

这可以用来检查div是否可见,如果可见,它将滑动对象向上。

0

以下是一个完整的事件驱动方法:

  • 自定义事件处理图层的“召唤”和“关闭”,以免影响其他基于点击的事件
  • 当相关图层实际可见时,document.body 仅监听关闭事件

代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript">

$(function()
{
  var $layer = $('#layer');
  var $body  = $('html');

  $layer
    .bind( 'summon', function( e )
    {
      $layer.show();
      $body.bind( 'click', dismissLayer );
    } )
    .bind( 'dismiss', function( e )
    {
      $layer.hide();
      $body.unbind( 'click', dismissLayer );
    } )
    .click( function( e )
    {
      e.stopPropagation();
    })
    .trigger( 'dismiss' )
  ;

  function dismissLayer( e )
  {
    $layer.trigger( 'dismiss' );
  }

  // This is optional - this just triggers the div to 'visible'
  $('#control').click( function( e )
  {
    var $layer = $('#layer:hidden');
    if ( $layer.length )
    {
      $layer.trigger( 'summon' );
      e.stopPropagation();
    }
  } );
});

</script>

<style type="text/css">
#layer {
  position: absolute;
  left: 100px;
  top: 20px;
  background-color: red;
  padding: 10px;
  color: white;
}
#control {
  cursor: pointer;
}
</style>

</head>
<body>

<div id="layer">test</div>
<span id="control">Show div</span>

</body>
</html>

我知道这是很多代码,但这里仅展示一种不同的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接