将事件处理程序附加到 children、parent 和文档

Attaching an event handler to children, the parent, and the document

这就是我想要的。页面上有几个框。每个框都有 children,其中包括一些可点击的 divs 和文本。当用户单击可单击的 div 时,应显示一条警告,说明 div 已被单击。如果他们单击文本,则不会发生任何事情。这就是我觉得棘手的地方。

当他们点击盒子时,盒子应该有一个名为 open 的 class,当他们点击不是盒子的东西或盒子的 children 时, class open 应该被删除。如果他们点击可点击的 div,那应该不会影响框的 class。

因此,如果用户单击另一个框,第一个框仍应具有 open class,而新框也应具有 open class,但是如果他们单击 header 或 body 或框以外的任何其他内容,则应删除 open class。请记住,如果点击可点击的 div 应该会触发相应的警报。

这里好像有很多事件定位,不知道你有没有好的解决方案。

仅出于演示目的,如果盒子有 open class,请将盒子的背景更改为绿色。如果他们单击 header 或 body 或其他 div 之类的其他内容,则该框应该具有钢蓝色(原始颜色)。如果他们点击可点击的 child div 框的背景应该是绿色的并且应该触发警报。

这是一些代码:

$(document).on("click", function(e) {
  //is there somthing like:
  // if `this` is not the box or children of box remove the
  // class `open` from box. this way if they click on header or body I could remove 
  //the `open` class from box
  if (e.target == this) {
    $(".box").removeClass("open")
  } else if ($(e.target).hasClass("box")) {
    $(e.target).addClass("open")
  }
  if ($(e.target).hasClass("test1")) {
    alert("test1")
  }
  if ($(e.target).hasClass("test2")) {
    alert("test2 clicked")
  }
  if ($(".box").hasClass("open")) {
    $(this).css("background", "green")
  }
})
.box {
  margin: 4em 5em;
  background: steelblue;
  width: 15em;
  height: 8em;
  padding: .1em;
}
.clicker {
  width: 5em;
  background: lightgreen;
  padding: .2em;
  cursor: pointer;
}
.header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3em;
  background: tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="header">header</div>
<div class="box">
  <p>this is the box</p>
  <p class="test1 clicker">Test click</p>
  <p class="test2 clicker">Test click 2</p>
</div>
<div class="box">
  <p>this is the box</p>
  <p class="test1 clicker">Test click</p>
  <p class="test clicker">Test click 2</p>
</div>

我认为只需调整条件就可以做到

$(document).on("click", function(e) {
  //is there somthing like:
  // if `this` is not the box or children of box remove the
  // class `open` from box. this way if they click on header or body I could remove 
  //the `open` class from box

  var $target = $(e.target);

  var $clicker = $target.closest('.clicker');
  if ($clicker.length) {
    if ($clicker.hasClass("test")) {
      $('#clicked').html("test")
    } else if ($clicker.hasClass("test1")) {
      $('#clicked').html("test1")
    } else if ($clicker.hasClass("test2")) {
      $('#clicked').html("test2")
    }
  }

  var $box = $target.closest('.box');
  if ($box.length) {
    $box.addClass('open');
  } else {
    $('.box.open').removeClass('open');
  }
})
.box {
  margin: 4em 5em;
  background: steelblue;
  width: 15em;
  height: 8em;
  padding: .1em;
}
.box.open {
  background-color: lightgrey;
}
.clicker {
  width: 5em;
  background: lightgreen;
  padding: .2em;
  cursor: pointer;
}
.header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3em;
  background: tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header">header:
  <div id="clicked"></div>
</div>
<div class="box">
  <p>this is the box</p>
  <p class="test1 clicker">Test click</p>
  <p class="test2 clicker">Test click 2</p>
</div>
<div class="box">
  <p>this is the box</p>
  <p class="test1 clicker">Test click</p>
  <p class="test clicker">Test click 2</p>
</div>