javascript - 如何防止子(孙)点击事件上的父点击事件?

标签 javascript html jquery css

我有一个父 div,单击它会显示其中一个子 div,再次单击父 div 将切换该子 div 并再次隐藏它。我在该子 div 内有一个开关,它将作为场景后面的复选框。我的代码的问题是,当我单击该开关切换时,它会触发切换切换事件以及父级单击事件。

我已经尝试了在堆栈溢出中找到的类似问题的可能解决方案,但没有取得任何成功。我在子点击事件上尝试了 e.stopPropagation(); ,在父点击事件上尝试了 if(e.target == this) 但没有任何帮助。 任何帮助将不胜感激。

请不要将其标记为重复,因为我已经尝试了所有给定的解决方案,但没有任何效果。谢谢。

$(".parent-block").click(function(e){
  $(this).find("i").toggleClass("fa-chevron-down");
  $(this).find("i").toggleClass("fa-chevron-up");
  $(this).children(".second-child").slideToggle();
})

$("input[type=checkbox]").change(function(e){
  if($(this).is(":checked")){
    $(this).closest('.switch-toggle-div').children('.on-off-label').html("ON");
  } else {
    $(this).closest('.switch-toggle-div').children('.on-off-label').html("OFF");
  }
  // e.stopPropagation();
});
.parent-block {
    border: 1px solid Blue;
    border-radius: 5px;
    margin-bottom: 9px;
    cursor: pointer;
}

.parent-block > div {
    margin: auto 10px;
}

.first-child {
    display: flex;
    justify-content: space-between;
    background: #FFFFFF 0% 0% no-repeat padding-box; 
}

.first-child > p {
    margin: auto 5px;
    padding: 5px;
}
.first-child > i {
    margin: auto 20px;
    color: #D6D6D6;
}

.second-child > p{
    margin: 0 5px;
    padding: 1px 5px;
    color: #A3ADB8;
    font-size: 11px;
}

.grand-child-flex {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  margin-bottom: 8px;
  padding: 10px 15px 10px 20px;
}

.grand-child-flex > p {
    margin: auto 10px;
    font-size: 12px;
}

.switch {
    position: relative;
    display: inline-block;
    width: 33px;
    height: 16px;
    margin: auto 10px;
}

.switch input { 
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #E4E4E4;
    -webkit-transition: .4s;
    transition: .4s;
}
  
.slider:before {
    position: absolute;
    content: "";
    height: 12px;
    width: 12px;
    left: 3px;
    bottom: 2px;
    background-color: white;
    -webkit-transition: .4s;
    transition: .4s;
}

input:checked + .slider {
    background-color: #21D59B;
}

input:focus + .slider {
    box-shadow: 0 0 1px #21D59B;
}
  
input:checked + .slider:before {
    -webkit-transform: translateX(15px);
    -ms-transform: translateX(15px);
    transform: translateX(15px);
}
  
  /* Rounded sliders */
.slider.round {
    border-radius: 1000px;
}
  
.slider.round:before {
    border-radius: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" 
    integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<div class="parent-block">
  <div class="first-child">
    <p>News</p>
    <i class="fas fa-chevron-down"></i>
  </div>
  
  <div class="second-child" style="display: none;">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
    <div class="grandchild-flex">
      <p>Notifications</p>
      <div class="switch-toggle-div">
        <span class="on-off-label">ON</span>
        <label class="switch">
          <input type="checkbox" checked>
          <span class="slider round"></span>
        </label>
      </div>
    </div>
  </div>
</div>

<div class="parent-block">
  <div class="first-child">
    <p>Alerts</p>
    <i class="fas fa-chevron-down"></i>
  </div>
  
  <div class="second-child" style="display: none;">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
    <div class="grandchild-flex">
      <p>Notifications</p>
      <div class="switch-toggle-div">
        <span class="on-off-label">ON</span>
        <label class="switch">
          <input type="checkbox" checked>
          <span class="slider round"></span>
        </label>
      </div>
    </div>
  </div>
</div>

演示:jsfiddle

最佳答案

即使您停止在复选框的“更改”事件上传播,导致更改的“单击”事件仍会传播到其祖先。

您可以停止传播 <label> 上的点击事件(或复选框和父 block 之间的任何祖先):

$('.switch').on('click', function(e) {
  e.stopPropagation();
});

这是一个演示:

$(".parent-block").on('click', function() {
  $(this).find("i").toggleClass("fa-chevron-down");
  $(this).find("i").toggleClass("fa-chevron-up");
  $(this).children(".second-child").slideToggle();
})

$("input[type=checkbox]").on('change', function() {
  if ($(this).is(":checked")) {
    $(this).closest('.switch-toggle-div').children('.on-off-label').html("ON");
  } else {
    $(this).closest('.switch-toggle-div').children('.on-off-label').html("OFF");
  }
});

$('.switch').on('click', function(e) {
  e.stopPropagation();
});
.parent-block {
  border: 1px solid Blue;
  border-radius: 5px;
  margin-bottom: 9px;
  cursor: pointer;
}

.parent-block>div {
  margin: auto 10px;
}

.first-child {
  display: flex;
  justify-content: space-between;
  background: #FFFFFF 0% 0% no-repeat padding-box;
}

.first-child>p {
  margin: auto 5px;
  padding: 5px;
}

.first-child>i {
  margin: auto 20px;
  color: #D6D6D6;
}

.second-child>p {
  margin: 0 5px;
  padding: 1px 5px;
  color: #A3ADB8;
  font-size: 11px;
}

.grand-child-flex {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  margin-bottom: 8px;
  padding: 10px 15px 10px 20px;
}

.grand-child-flex>p {
  margin: auto 10px;
  font-size: 12px;
}

.switch {
  position: relative;
  display: inline-block;
  width: 33px;
  height: 16px;
  margin: auto 10px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #E4E4E4;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 12px;
  width: 12px;
  left: 3px;
  bottom: 2px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked+.slider {
  background-color: #21D59B;
}

input:focus+.slider {
  box-shadow: 0 0 1px #21D59B;
}

input:checked+.slider:before {
  -webkit-transform: translateX(15px);
  -ms-transform: translateX(15px);
  transform: translateX(15px);
}


/* Rounded sliders */

.slider.round {
  border-radius: 1000px;
}

.slider.round:before {
  border-radius: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<div class="parent-block">
  <div class="first-child">
    <p>News</p>
    <i class="fas fa-chevron-down"></i>
  </div>

  <div class="second-child" style="display: none;">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
    <div class="grandchild-flex">
      <p>Notifications</p>
      <div class="switch-toggle-div">
        <span class="on-off-label">ON</span>
        <label class="switch">
          <input type="checkbox" checked>
          <span class="slider round"></span>
        </label>
      </div>
    </div>
  </div>
</div>

<div class="parent-block">
  <div class="first-child">
    <p>Alerts</p>
    <i class="fas fa-chevron-down"></i>
  </div>

  <div class="second-child" style="display: none;">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
    <div class="grandchild-flex">
      <p>Notifications</p>
      <div class="switch-toggle-div">
        <span class="on-off-label">ON</span>
        <label class="switch">
          <input type="checkbox" checked>
          <span class="slider round"></span>
        </label>
      </div>
    </div>
  </div>
</div>

关于javascript - 如何防止子(孙)点击事件上的父点击事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68579895/

相关文章:

javascript - ReactJS Devtools 只显示 <TopLevel>

javascript - 如何捕获文本中某个单词后面出现的多个数字?

html - 将 flexbox 网格转换为以不同顺序堆叠

javascript - 使用 jquery 的 addClass 方法覆盖样式表

javascript - 用于打开网页、编辑输入字段和提交表单的脚本

javascript - @onmouseup 没有在 vuejs 2 上触发

javascript - 使用 Jquery 使绝对按钮具有粘性动画

javascript - Ajax错误: index. html :17 Uncaught InvalidStateError: Failed to execute 'send' on 'XMLHttpRequest' : The object's state must be OPENED. sendAjax

jquery - jquery-rails 缺少rails.js

javascript - JS代码运行很慢