$(event.target).closest()。隐藏div的长度并不总是有效。任何替代方案?

时间:2017-11-15 02:44:52

标签: javascript jquery html css

我使用$(event.target).closest("#divID").length隐藏div当用户点击它之外但如果div可见,我点击日期(datepicker)就赢了# 39;隐藏div

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

有什么更好的解决方案可以在点击其他内容时隐藏div吗?

我的实施错了吗?

ps:#log_in是登录按钮,#log_in_form是我要在外部点击时隐藏的form#log_in_container是包含#log_in的div }和#log_in_form

更新:我刚注意到在Windows 10和Linux ubuntu 16.04上的消失并不相同。在使用谷歌浏览器使用谷歌浏览器的PC上,表格在第一次点击时就会消失(这是理想的功能),但如果我选择日期,它仍然不会消失。虽然在谷歌Chrome上的Linux ubuntu 16.04上,它就像我上面描述的那样(在选择日期时没有消失,并且在你选择的第一次点击时也不会消失)

示例基于Andrei对代码段

的回答

&#13;
&#13;
$(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();
    }
})
&#13;
#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;
}
&#13;
<!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>
&#13;
&#13;
&#13;

在上面的代码段中,如果单击Log_in_button,则会显示Log_in_form。如果那样你点击它没有消失的日期,然后点击  在选择Log_in_form仍然没有消失,之后点击下一步选择Log_in_form仍然可见。我想这样做,以便它在这些场合消失(如选择弹出窗口)。这可能吗?

5 个答案:

答案 0 :(得分:4)

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

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

the W3C site上的图表很好地解释了捕获和气泡流,有关详细信息和跨浏览器实施,请参阅this question

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

&#13;
&#13;
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);
&#13;
#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;
}
&#13;
<!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>
&#13;
&#13;
&#13;

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

  

Linux上的Chrome 19:首先鼠标点击展开选项[点击事件未触发],然后点击仍然存在的选项或选项,触发点击事件。

由于这是一种您无法控制的浏览器行为,我不认为有任何解决方法 - 您只能处理它触发的事件。如果浏览器未触发该事件,则无法对其做出反应。

答案 1 :(得分:1)

您只需使用mouseup事件代替click即可在日期点击中使用。

&#13;
&#13;
$(document).on('mouseup', 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();
    }
})
&#13;
#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;
}
&#13;
<!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>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您的代码正常工作,但dateoicker <td>除外。这真的很奇怪

但是我们仍然可以使用jQuery ui datepicker中的onSelect方法来解决这个问题。

&#13;
&#13;
$(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();
    }
})
&#13;
#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;
}
&#13;
<!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({
			onSelect: function(i, e){
				$('#log_in_form').fadeOut();
			}
	  });
  	  });
  	</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>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

我建议使用事件_meta_child_details 0 child_name "Mayank" _meta_child_hobby "Cricket" child_dob "10/23/2017" 1 child_name "Dev" _meta_child_hobby "Hockey" child_dob "11/20/2017" 而不是mousedown,并检查点击是否发生在日志包装内,如此

click

准备好的整个文档看起来像这样

$(e.target).parents().has($('#log_in_container')).length

答案 4 :(得分:0)

为什么不使用onSelect的{​​{1}}事件,并手动触发datepickerbound的点击,因为它不会当您点击document内的日期时似乎被触发,无需更改有关事件的任何内容或在datepicker内编写单独的逻辑,只需在onSelect内添加更多逻辑即可1}}并触发它只需添加2行代码并保持原样。

您只需要更改.on('click')初始化,如下所示

datepicker

参见下面的演示

&#13;
&#13;
$("#datepicker").datepicker({
    onSelect: function (date, obj) {
        $(document).trigger('click')
    }
});
&#13;
$(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();
  }
})
&#13;
#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;
}
&#13;
&#13;
&#13;