toggleClass - 父级同级选择器 - 问题

时间:2015-11-21 09:02:19

标签: javascript jquery html

只是遇到了一些问题,我已经制作了以下脚本。

它在切换表单面板方面非常有效,但是当我开始与“活动”面板交互时。面板(即单击输入字段),活动类将从其父元素中删除,从而最小化面板。

$(function () {
    $('.options-list li').click(function () {
        $(this).toggleClass('active');
        $(this).parent().children('li').not(this).removeClass('active');
    });
});

有没有办法可以将切换功能仅限制为标题内容?

https://jsfiddle.net/os883y47/

我认为这是由于' Title'在<'>>内没有自己的包含元素,所以我将文本包装在<' span'>中元素与这似乎解决了最小化问题的形式,但现在“活跃”了class isn不被删除(假设它现在是一个子选择器问题?)。

https://jsfiddle.net/avk7e30a/

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:2)

这是因为事件冒泡到li而发生的。 input上的点击事件会冒泡到li元素,并再次执行事件处理程序。要阻止这种情况发生,请在子元素事件处理程序上使用event.stopPropagation()

  

阻止事件冒泡DOM树,防止任何父处理程序收到事件通知。

Updated Fiddle

添加以下代码

$('.active-panel').click(function (e) {
    e.stopPropagation(); // Stop event from bubbling up
});

$(function() {
  $('.options-list li').click(function() {
    $(this).toggleClass('active');
    $(this).parent().children('li').not(this).removeClass('active');
  });

  $('.active-panel').click(function(e) {
    e.stopPropagation();
  });
});
.options-list {
  border: 1px solid #d5d6d7;
  padding: 0;
  margin-bottom: 30px;
}
.option {
  list-style: none;
  border-bottom: 1px solid #dadada;
  font: 16px/56px avenir_65regular !important;
  color: #333;
}
.options-list .option.active {
  color: #004ebc;
}
.options-list .option.active:before {
  background-color: #004ebc !important;
  border: 5px solid #83ace0 !important;
}
.options-list .option:before {
  content: "";
  background-color: #fff;
  border-radius: 16px;
  border: 5px solid #004ebc;
  height: 18px;
  margin: 0 10px;
  width: 18px;
  position: relative;
  top: 3px;
  box-sizing: border-box;
  display: inline-block;
}
.panel {
  height: 0;
  overflow: hidden;
  background: #f9f9f9;
  border-top: 1px solid #d5d6d7;
  transition: all 0.5s linear;
  transition: height 0.25s ease-in-out;
  /* visibility: hidden; */
  /* opacity: 0; */
  /* transition: visibility 0s, opacity 0.5s linear; */
}
.option.active > .panel {
  /* visibility: visible; */
  /* opacity: 1; */
  height: 100%;
  padding: 25px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="options-list">
  <li class="option active">FORM FIELD 1
    <div class="panel active-panel">
      <div class="form-field">
        <label class="form-label black">Sub Field</label>
        <input class="form-input" type="text" />
      </div>
      <div class="form-field flt">
        <label class="form-label black">Sub Field</label>
        <input class="form-input half" type="text" />
        <input class="form-input half" type="text" />
      </div>
      <div class="form-field flt">
        <label class="form-label black cvc">Sub Field</label>
        <input class="form-input half" type="text" />
      </div>
    </div>
  </li>
  <li class="option">FORM FIELD 2
    <div class="panel"></div>
  </li>
  <li class="option">FORM FIELD 3
    <div class="panel"></div>
  </li>
</ul>

阅读:What is event bubbling and capturing?

答案 1 :(得分:0)

HTML是一样的。

JQuery的

$(function() {
    $('.options-list li').click(function(){
        $(this).closest('.options-list').find('.active').removeClass('active');
        $(this).addClass('active');
    });
});

这是一个小提琴:https://jsfiddle.net/os883y47/2/

答案 2 :(得分:0)

我会将以下代码添加为处理程序中的第一个语句,因此只有当点击位于li元素的直接子项(.options-list)时才会继续:

$('.options-list li').click(function(e){
    if (!$(e.target).parent().is('.options-list')) {
        return;
    }
    ...

这是fiddle

答案 3 :(得分:0)

将您的代码更改为以下

$(function() {
    $('.options-list li').click(function(e){
        if (e.target === this) {
           $(this).toggleClass('active');
           $(this).parent().children('li').not(this).removeClass('active');
        }
    });
}); 

这是因为您将click事件添加到父级,因此即使您单击其子级,也会触发事件。因此需要验证以确认它是父元素

答案 4 :(得分:0)

您可能希望阻止面板上的点击事件:

的JavaScript

$('.options-list li .panel').click(function(evt){
    evt.preventDefault();
    return false;
});

JSFiddle