JQuery事件冒泡问题

时间:2017-06-05 10:25:31

标签: javascript jquery

JSFiddle:https://jsfiddle.net/3v2qav58/

下拉菜单出现问题。

我的子类别列表项目中有一个ul /下拉列表的问题,所以我抓住了列表项并使用'.find()'来获取下拉列表,然后尝试使用slideToggle它。

问题是我有3个列表项,当我点击其他列表项时,它们也会打开并关闭其他列表项,例如,第一个列表项只有下拉列表,但是如果单击第2个/第3个列表项,它们也是切换。

我认为这与事件冒泡有关,因为我认为'.find()'只是向下而不是向上?

有人可以解释为什么会发生事件冒泡以及如何解决这个问题吗?

干杯

HTML

<ul class="dropdown">
  <li class="dropdown-item">
    <a href="">Cat 1</a>
    <ul class="sub-dropdown">
      <li class="dropdown-sub-item">
        <a href="#">Sub Cat 1</a>
        <ul class="sub-dropdown-child">
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 1</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 2</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 3</a></li>
        </ul>
      </li>

CSS

.sub-dropdown,
.sub-dropdown-child {
  display: none;
}

JQuery的

var dropdownItem = $(".dropdown-item");
var dropdownSubItem = $(".sub-dropdown");
var DropdownSubItem = $(".dropdown-sub-item");
var subDropdownChild = $(".sub-dropdown-child");

// Open
dropdownItem.on("click", function(e) {
  e.preventDefault();
  dropdownSubItem.show();

  // Open sub cat
  dropdownSubItem.on("click", function(e) {
    e.stopPropagation();
    $(this).find(subDropdownChild).slideToggle();
  });
});

2 个答案:

答案 0 :(得分:1)

将您的JS更改为以下内容:

$(".dropdown-item").on("click", function(e) {
  e.preventDefault();
  $(this).find(".sub-dropdown").toggle();
});
$(".sub-dropdown").on("click", function(e) {
  e.stopPropagation();
  $(this).find(".sub-dropdown-child").slideToggle();
});
$(".sub-dropdown-child").on("click", function(e) {
  e.stopPropagation();
});
.sub-dropdown,
.sub-dropdown-child {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="dropdown">
  <li class="dropdown-item">
    <a href="">Cat 1</a>
    <ul class="sub-dropdown">
      <li class="dropdown-sub-item">
        <a href="#">Sub Cat 1</a>
        <ul class="sub-dropdown-child">
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 1</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 2</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 3</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li class="dropdown-item">
    <a href="">Cat 2</a>
    <ul class="sub-dropdown">
      <li class="dropdown-sub-item">
        <a href="#">Sub Cat 2</a>
        <ul class="sub-dropdown-child">
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 1</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 2</a></li>
          <li class="sub-dropdown-child-item"><a href="#">Sub Cat Child 3</a></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

您的代码的问题在于您在哪里显示所有子项,而不仅仅是所点击子项的子项:

dropdownSubItem.show(); //This shows all sub-items

我将其替换为:

$(this).find(".sub-dropdown").toggle();

此外,在单击根项时,您对子项进行了多次事件绑定:

dropdownItem.on("click", function(e) {
  ...
  dropdownSubItem.on("click", function(e) {
    ...
  });
  ...
});

每次点击都会导致事件绑定。

答案 1 :(得分:0)

2件事:

  
      
  • 分别在第一个活动之外保留子项目的点击事件。
  •   
  • 您必须已将点击事件附加到li.DropdownSubItem而不是ul.dropdownSubItem
  •   

以下是更新后的代码和 Fiddle

// Open
dropdownItem.on("click", function(e) {
  e.preventDefault();
  dropdownSubItem.show();
});

// Open sub cat
DropdownSubItem.on("click", function(e) {
  $(this).find(subDropdownChild).slideToggle();
  e.stopImmediatePropagation();
});