javascript - $(event.target).closest().length 隐藏 div 并不总是有效。还有其他选择吗?

标签 javascript jquery html css

我使用 $(event.target).closest("#divID").length隐藏 div当用户在其外部单击但在 div 的情况下是可见的,我点击一个日期(日期选择器)它不会隐藏 div .

另外,如果我点击 <select>有时它会隐藏它有时它不会。

是否有更好的解决方案来在单击其他内容时隐藏 div?

我的实现有误吗?

附注:#log_in是登录按钮,#log_in_formform我想隐藏在外部点击和#log_in_container是包含 #log_in 的 div和 #log_in_form

更新:我刚刚注意到 Windows 10 和 linux ubuntu 16.04 上的消失情况不同。在使用谷歌浏览器的 Windows 10 电脑上,我第一次点击选择时,表单消失(这是理想的功能),但如果我选择日期,它仍然不会消失。在 linux ubuntu 16.04 和 google chrome 上,它就像我上面描述的那样(不会在日期选择时消失,也不会在您第一次点击选择时消失)

示例基于 Andrei 对片段的回答

$(document).on('click', function(e){
    if($(e.target).closest('#log_in').is('#log_in'))
    {
      $('#log_in_form').fadeIn();
    }
    else if(!$(e.target).closest('#log_in_container').is('#log_in_container'))
    {
      $('#log_in_form').fadeOut();
    }
})
#log_in_container{
  display:inline-block;
  width:122px;
  height:58px;
  margin-left:60px;
  background-color:gray;
}

#log_in{
  display:block;
  width:120px;
  height:28px;
  text-align: center;
  border: 1px solid red;
  font-size:16px;
  background-color:yellow;
  vertical-align: top;
}

#log_in_form{
  display:none;
  position:absolute;
  width:120px;
  height:28px;
  text-align: center;
  background-color: green;
  border: 1px solid blue;
}

.type{
  display:inline-block;
  width:120px;
  height:30px;
  text-align: center;
  border: 1px solid red;
  font-size:16px;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    <!-- ~~~~~~~~~~~~~~~Date picker ~~~~~~~~~~~~~~~ -->
	<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
	<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
	<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
	<script>
  	  $( function()
	  {
    	  $( "#datepicker" ).datepicker();
  	  });
  	</script>
    <title></title>
  </head>
  <body>
  <select class="type">
      <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select hero</p></option>
      <option value="0">Spiderman</option>
      <option value="1">Iron man</option>
      <option value="2">Deadpool</option>
  </select>
  <select class="type">
      <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select food</p></option>
      <option value="0">Kebab</option>
      <option value="1">Mousaka</option>
      <option value="2">Noodles</option>
  </select>
  <div id="log_in_container">
      <div  id="log_in">Log_In_button</div>
      <div id ="log_in_form">login_form</div>
  </div>
  <div id="datepicker"></div>


  </body>
</html>

在上面的代码片段中,如果您单击 Log_in_button,就会出现 Log_in_form。如果然后你点击一个日期它不会消失,然后点击 选择 Log_in_form 仍然没有消失,然后单击下一个选择 Log_in_form 仍然可见。我想让它在这些场合消失(就像选择弹出窗口一样)。这可能吗?

最佳答案

jQuery 仅适用于事件冒泡(事件从目标元素开始并向上 DOM 树,引发点击事件直到到达顶层 document )。正如您在 ui-datepicker 中看到的那样,潜在的问题是, 是元素可以通过使用 event.stopPropagation() 取消冒泡, 和 document永远不会得到它。

相反,您需要使用原始 Javascript 事件捕获,其中顶级元素捕获发生的事件并将其向下传递到 DOM 树。

the W3C site 上的图表很好地解释了捕获和气泡流,请参阅 this question了解更多详情和跨浏览器实现。

您的代码所需的更改很小,您只需使用 document.addEventListener而不是 $(document).on :

document.addEventListener("click", function(e){
    if($(e.target).closest('#log_in').is('#log_in'))
    {
      $('#log_in_form').fadeIn();
    }
    else if(!$(e.target).closest('#log_in_container').is('#log_in_container'))
    {
      $('#log_in_form').fadeOut();
    }
}, true);
#log_in_container{
  display:inline-block;
  width:122px;
  height:58px;
  margin-left:60px;
  background-color:gray;
}

#log_in{
  display:block;
  width:120px;
  height:28px;
  text-align: center;
  border: 1px solid red;
  font-size:16px;
  background-color:yellow;
  vertical-align: top;
}

#log_in_form{
  display:none;
  position:absolute;
  width:120px;
  height:28px;
  text-align: center;
  background-color: green;
  border: 1px solid blue;
}

.type{
  display:inline-block;
  width:120px;
  height:30px;
  text-align: center;
  border: 1px solid red;
  font-size:16px;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    <!-- ~~~~~~~~~~~~~~~Date picker ~~~~~~~~~~~~~~~ -->
	<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
	<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
	<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
	<script>
  	  $( function()
	  {
    	  $( "#datepicker" ).datepicker();
  	  });
  	</script>
    <title></title>
  </head>
  <body>
  <select class="type">
      <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select hero</p></option>
      <option value="0">Spiderman</option>
      <option value="1">Iron man</option>
      <option value="2">Deadpool</option>
  </select>
  <select class="type">
      <option value="null" disabled="disabled" selected="selected"><p style="color:gray;">Select food</p></option>
      <option value="0">Kebab</option>
      <option value="1">Mousaka</option>
      <option value="2">Noodles</option>
  </select>
  <div id="log_in_container">
      <div  id="log_in">Log_In_button</div>
      <div id ="log_in_form">login_form</div>
  </div>
  <div id="datepicker"></div>


  </body>
</html>

正如您之前提到的,初始 <select>在 Windows 上的 Chrome 中工作,但在 Linux 上的 Chrome 中不工作。浏览器通常将表单控件的呈现交给操作系统以实现视觉一致性,但这可能会导致行为不一致。 <select> s 可能是最不一致的基本表单控件,因为它们增加了复杂性。 This question演示了这个问题,特别是:

Chrome 19 on Linux: First mouse click expands options [click event not triggered], subsequent click on either the still-present select, or the options, triggers click event.

由于这是一种您无法控制的浏览器行为,我认为没有任何解决方法 - 您只能处理它触发的事件。如果浏览器没有触发该事件,您将无法对其使用react。

关于javascript - $(event.target).closest().length 隐藏 div 并不总是有效。还有其他选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47298521/

相关文章:

html - 给 SLIM 文件起什么名字? 。瘦? .html. slim ?

javascript - Highcharts 桑基图,系列颜色

javascript - 对象数组的深度减少(可能是采摘?)

javascript - 为什么使用循环从数组开始到结束迭代比从开始到结束和结束到开始迭代更快?

javascript - 为什么我的 jQuery SlideDown 动画滞后/跳跃?

jquery - 在 jQuery 中,如何确认某个元素是其类中的第一个元素?

javascript - 将外部 json 文件转换为 html 表

javascript - 更改 JavaScript 中的日期格式

javascript - 没有元素时拖放不起作用

html - 谷歌地图和页脚之间的小差距