开发者问题收集

单击任意位置时隐藏元素,无需检查每次 DOM 单击

2015-04-09
79

我有一个下拉列表,单击 DIV 时会打开该列表:

<div class="unitwrap">

    <span class="dropdown">Click this text</span>

    <ul class="units">
        <li>Second</li>
        <li>Minute</li>
        <li>Hour</li>
    </ul>

</div>

$('body')
    // open dropdown
    .on("click", '.unitwrap', function() {

        $(this).toggleClass('active');

    });

.active .units { display:block }

我想设置一个事件来关闭下拉菜单,但我不想在每次点击时都检查 dom:

$('body').on('click', function(){ $('.unitWrap').removeClass('active') });

单击下拉元素以外的任何地方时,关闭打开的元素的最佳方法是什么?

这里有一个示例 也在 pastebin

$('body')
  // open dropdown
  .on("click", '.unitwrap', function() {

    $(this).toggleClass('active');

  });
.unitwrap {
  cursor: pointer;
  background: red;
}

.unitwrap.active .units {
  display: block;
}

.unitwrap .dropdown:after {
  display: inline-block;
  margin-left: 4px;
  content: '';
  border-top: 5px solid transparent;
  border-top: 5px solid transparent;
  border-right: 5px solid transparent;
  border-left: 5px solid transparent;
}

.unitwrap .units {
  font-size: 13px;
  position: absolute;
  z-index: 5;
  display: none;
  width: 140px;
  margin-top: 7px;
  padding: 7px 0;
  text-transform: none;
  border-radius: 3px;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .13);
}

.unitwrap .units li {
  font-weight: bold;
  display: block;
  padding: 4px 10px 4px 30px;
  cursor: pointer;
  color: #a8a8a8;
}

.unitwrap .units li em {
  font-weight: normal;
  font-style: normal;
  float: right;
  color: #ccc;
}

.unitwrap .units li.active {
  color: #676767;
}

.unitwrap .units li.active:before {
  font: 11px;
  position: absolute;
  left: 10px;
  margin-top: 3px;
  color: inherit;
}

.unitwrap .units li:hover,
.unitwrap .units li:hover em {
  color: #fff;
  background: #2cb6f7;
}

.unitwrap .units.active {
  display: block;
}
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>

<div class="unitwrap">

  <span class="dropdown">Click this text</span>

  <ul class="units">
    <li>Second</li>
    <li>Minute</li>
    <li>Hour</li>
  </ul>

</div>
3个回答

只需更改标记并使用 mouseleave 事件。

$('.unitwrap')
	// open dropdown
	.on("click", function() {
		$(this).toggleClass('active');
	})

    // close dropdown
    .on("mouseleave", function () {
        $(this).toggleClass('active');
    });
.unitwrap
{
    cursor: pointer;
    background:red;
}

.unitwrap.active .units
{
    display: block;
}

.active .units-holder {
  padding: 7px 0;
}

.unitwrap .dropdown:after
{
    display: inline-block;

    margin-left: 4px;

    content: '';

    border-top: 5px solid transparent;
    border-top: 5px solid transparent;
    border-right: 5px solid transparent;
    border-left: 5px solid transparent;
}

.unitwrap .units
{
    font-size: 13px;

    position: absolute;
    z-index: 5;

    display: none;

    width: 140px;
    margin: 0;
    padding: 7px 0;

    text-transform: none;

    border-radius: 3px;
    background: #fff;
    box-shadow: 0 1px 4px rgba(0,0,0,.13);
}

.unitwrap .units li
{
    font-weight: bold;

    display: block;

    padding: 4px 10px 4px 30px;

    cursor: pointer;

    color: #a8a8a8;
}

.unitwrap .units li em
{
    font-weight: normal;
    font-style: normal;

    float: right;

    color: #ccc;
}

.unitwrap .units li.active
{
    color: #676767;
}

.unitwrap .units li.active:before
{
    font: 11px;

    position: absolute;
    left: 10px;

    margin-top: 3px;

    color: inherit;
}

.unitwrap .units li:hover,
.unitwrap .units li:hover em
{
    color: #fff;
    background: #2cb6f7;
}

.unitwrap .units.active
{
    display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="unitwrap">
  
  <span class="dropdown">Click this text</span>

  <div class="units-holder">
    <ul class="units">
    <li>Second</li>
    <li>Minute</li>
    <li>Hour</li>
  </ul>
  </div>
  
</div>

更新答案 - 使用点击事件

$('.unitwrap')
	// open dropdown
	.on("click", function() {

		$(this).toggleClass('active');

	});

$('.mask')
    
    .on('click', function () {
        $(this).toggleClass('active');
    });
.unitwrap
{
    cursor: pointer;
    background:red;
}

.mask {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  display: none;
  cursor: default;
  z-index: 2;
}

.active .mask {
  display: block;
}

.unitwrap.active .units
{
    display: block;
}


.unitwrap .dropdown:after
{
    display: inline-block;

    margin-left: 4px;

    content: '';

    border-top: 5px solid transparent;
    border-top: 5px solid transparent;
    border-right: 5px solid transparent;
    border-left: 5px solid transparent;
}

.unitwrap .units
{
    font-size: 13px;

    position: absolute;
    z-index: 5;

    display: none;

    width: 140px;
    margin-top: 7px;
    padding: 7px 0;

    text-transform: none;

    border-radius: 3px;
    background: #fff;
    box-shadow: 0 1px 4px rgba(0,0,0,.13);
}

.unitwrap .units li
{
    font-weight: bold;

    display: block;

    padding: 4px 10px 4px 30px;

    cursor: pointer;

    color: #a8a8a8;
}

.unitwrap .units li em
{
    font-weight: normal;
    font-style: normal;

    float: right;

    color: #ccc;
}

.unitwrap .units li.active
{
    color: #676767;
}

.unitwrap .units li.active:before
{
    font: 11px;

    position: absolute;
    left: 10px;

    margin-top: 3px;

    color: inherit;
}

.unitwrap .units li:hover,
.unitwrap .units li:hover em
{
    color: #fff;
    background: #2cb6f7;
}

.unitwrap .units.active
{
    display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="unitwrap">
  
  <span class="dropdown">Click this text</span>

  
    <ul class="units">
    <li>Second</li>
    <li>Minute</li>
    <li>Hour</li>
  </ul>
 
  
  <div class="mask"></div>
  
</div>
Vigneswaran Marimuthu
2015-04-09

有几个步骤:

  1. 打开元素时将处理程序附加到主体

    function onBodyClick() { // 检查是否单击下拉菜单上或下拉菜单内 // 如果不是,则关闭下拉菜单

    $(document.body).on('click', onBodyClick);

  2. 当手动或通过上述处理程序关闭下拉菜单时,解除绑定点击处理程序

    $(document.body).off('click', onBodyClick);

alexreardon
2015-04-09
 $('.unitwrap').click(function() {
      $(this).toggleClass('active');
  });

    $(window).click(function(event){
      if(!$(event.target).hasClass('active')){
        $('.unitwrap').removeClass('active');
      }
    });
Nisar
2015-04-09