jQuery在点击操作期间选择了错误的元素

时间:2017-03-17 17:49:16

标签: javascript jquery css jquery-selectors

我在这里有以下代码示例:

$(document).ready(function() {

  $('.children a.txtlink').on("click", function(e) {
    // toggle the icons when the text link is pressed

    jQuery(this).parent().find('ul:first').toggle(); // toggle the next UL

    if (jQuery(this).parent().find('i').hasClass("fa-chevron-down")) {
      jQuery(this).parent().find('i').removeClass("fa-chevron-down").addClass("fa-chevron-up");
    } else {
      jQuery(this).parent().find('i').removeClass("fa-chevron-up").addClass("fa-chevron-down");
    }

    e.stopPropagation();
    e.preventDefault();
  });

  $('.children i.arrows').on("click", function(e) {
    // toggle the icons when the chevron is pressed

    jQuery(this).parent().find('ul:first').toggle(); // toggle the next UL

    if (jQuery(this).hasClass("fa-chevron-down")) {
      jQuery(this).removeClass("fa-chevron-down").addClass("fa-chevron-up");
    } else {
      jQuery(this).removeClass("fa-chevron-up").addClass("fa-chevron-down");
    }

    e.stopPropagation();
    e.preventDefault();
  });


});
.navbar_menu {
  background: #222222;
}

.menu {
  border-top: 1px solid #2D2D2D;
}

.menu ul {
  padding: 0;
  margin: 0;
}

.menu li {
  list-style: none;
  position: relative;
}

.menu li i {
  padding-right: 3px;
}

.menu a.txtlink {
  color: #ccc;
  display: block;
  font-size: 16px;
  padding: 10px;
  padding-right: 0;
  border-bottom: 1px solid #2D2D2D;
  text-decoration: none;
}

.menu a.txtlink:hover {
  background: #111111;
  color: #ffffff;
  text-decoration: none;
}

.menu li.home a.txtlink::before {
  content: '\f015';
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transform: none;
}

.menu ul li {
  position: relative;
}

.menu ul li.children i.arrows {
  /* needed to show an icon in the mobile menu */
  position: absolute;
  top: 0;
  right: 0;
  padding: 14px;
  border-left: 1px solid #333333;
  margin: 0;
  cursor: pointer;
  display: block;
  color: #CCCCCC;
}

.menu .sub {
  display: none;
}

.menu ul li ul li a.txtlink {
  padding-left: 20px;
}

.menu ul li ul li ul li a.txtlink {
  padding-left: 40px;
}

.menu i.arrows:hover {
  background-color: #111111;
}

.menu ul li ul li {
  background-color: #333333;
}
<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<nav class="navbar_menu">

  <div class="menu">
    <ul>
      <li class="home"><a href="#" class="txtlink">Home</a></li>
      <li class="children">
        <a href="#" class="txtlink"><i class="fa fa-folder"></i>Menu 1</a>
        <ul class="sub">
          <li class="children">
            <a href="#" class="txtlink"><i class="fa fa-search"></i>Menu 1.1</a>
            <ul class="sub">
              <li><a href="#" class="txtlink"><i class="fa fa-user"></i>Menu 1.1.1</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa-tag"></i>Menu 1.1.2</a></li>
            </ul>
            <i class="arrows fa fa-chevron-down"></i>
          </li>
          <li><a href="#" class="txtlink">Menu 1.2</a></li>
          <li><a href="#" class="txtlink">Menu 1.3</a></li>
          <li><a href="#" class="txtlink"><i class="fa fa-clock-o"></i>Menu 1.4</a></li>
          <li><a href="#" class="txtlink"><i class="fa fa-search"></i>Menu 1.5</a></li>
        </ul>
        <i class="arrows fa fa-chevron-down"></i>
      </li>
      <li><a href="#" class="txtlink"><i class="fa "></i>Menu 2</a></li>
      <li class="children">
        <a href="#" class="txtlink"><i class="fa fa-folder"></i>Menu 3</a>
        <ul class="sub">
          <li class="children">
            <a href="#" class="txtlink"><i class="fa fa fa-search"></i>Menu 3.1</a>
            <ul class="sub">
              <li><a href="#" class="txtlink"><i class="fa fa-user"></i>Menu 3.1.1</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa-bookmark-o"></i>Menu 3.1.2</a></li>
            </ul>
            <i class="arrows fa fa-chevron-down"></i>
          </li>
          <li><a href="#" class="txtlink"><i class="fa"></i>Menu 3.2</a></li>
          <li><a href="#" class="txtlink"><i class="fa"></i>Menu 3.3</a></li>
          <li><a href="#" class="txtlink"><i class="fa fa fa-calendar"></i>Menu 3.4</a></li>
          <li><a href="#" class="txtlink"><i class="fa fa fa-search"></i>Menu 3.5</a></li>
        </ul>
        <i class="arrows fa fa-chevron-down"></i>
      </li>
      <li><a href="#" class="txtlink"><i class="fa fa-comments"></i>Menu 4</a></li>
    </ul>
  </div>

</nav>

问题是,当我使用小箭头展开/缩小菜单并正确交换箭头时,它工作正常。但是,当我单击文本元素时,菜单中的图标将全部替换为箭头。

示例:使用箭头时,搜索图标会保留在菜单中。当我点击文字链接时,它会被箭头替换。

我想我在这里使用了一个错误的jquery选择器但是因为我对jquery很新,我无法修复它。那么我的错误是什么?

当我点击箭头时

2 个答案:

答案 0 :(得分:1)

  1. 使用.children()代替.find()来确保只有直接 孩子们都包含在查询中。
  2. 您的onclick事件可以合并 使用$('.children > a.txtlink, .children > i.arrows')加入1个单个事件监听器。再次,使用>直接子选择器 确保我们不会查询嵌套的孩子。
  3. 它应该按预期工作:

    $(document).ready(function() {
    
      $('.children > a.txtlink, .children > i.arrows').on("click", function(e) {
        // toggle the icons when the text link is pressed
    
        jQuery(this).parent().children('ul:first').toggle(); // toggle the next UL
    
        if (jQuery(this).parent().children('i.arrows').hasClass("fa-chevron-down")) {
          jQuery(this).parent().children('i.arrows').removeClass("fa-chevron-down").addClass("fa-chevron-up");
        } else {
          jQuery(this).parent().children('i.arrows').removeClass("fa-chevron-up").addClass("fa-chevron-down");
        }
    
        e.stopPropagation();
        e.preventDefault();
      });
    });
    .navbar_menu {
      background: #222222;
    }
    
    .menu {
      border-top: 1px solid #2D2D2D;
    }
    
    .menu ul {
      padding: 0;
      margin: 0;
    }
    
    .menu li {
      list-style: none;
      position: relative;
    }
    
    .menu li i {
      padding-right: 3px;
    }
    
    .menu a.txtlink {
      color: #ccc;
      display: block;
      font-size: 16px;
      padding: 10px;
      padding-right: 0;
      border-bottom: 1px solid #2D2D2D;
      text-decoration: none;
    }
    
    .menu a.txtlink:hover {
      background: #111111;
      color: #ffffff;
      text-decoration: none;
    }
    
    .menu li.home a.txtlink::before {
      content: '\f015';
      display: inline-block;
      font: normal normal normal 14px/1 FontAwesome;
      font-size: inherit;
      text-rendering: auto;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      transform: none;
    }
    
    .menu ul li {
      position: relative;
    }
    
    .menu ul li.children i.arrows {
      /* needed to show an icon in the mobile menu */
      position: absolute;
      top: 0;
      right: 0;
      padding: 14px;
      border-left: 1px solid #333333;
      margin: 0;
      cursor: pointer;
      display: block;
      color: #CCCCCC;
    }
    
    .menu .sub {
      display: none;
    }
    
    .menu ul li ul li a.txtlink {
      padding-left: 20px;
    }
    
    .menu ul li ul li ul li a.txtlink {
      padding-left: 40px;
    }
    
    .menu i.arrows:hover {
      background-color: #111111;
    }
    
    .menu ul li ul li {
      background-color: #333333;
    }
    <script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
    <nav class="navbar_menu">
    
      <div class="menu">
        <ul>
          <li class="home"><a href="#" class="txtlink">Home</a></li>
          <li class="children">
            <a href="#" class="txtlink"><i class="fa fa-folder"></i>Menu 1</a>
            <ul class="sub">
              <li class="children">
                <a href="#" class="txtlink"><i class="fa fa-search"></i>Menu 1.1</a>
                <ul class="sub">
                  <li><a href="#" class="txtlink"><i class="fa fa-user"></i>Menu 1.1.1</a></li>
                  <li><a href="#" class="txtlink"><i class="fa fa-tag"></i>Menu 1.1.2</a></li>
                </ul>
                <i class="arrows fa fa-chevron-down"></i>
              </li>
              <li><a href="#" class="txtlink">Menu 1.2</a></li>
              <li><a href="#" class="txtlink">Menu 1.3</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa-clock-o"></i>Menu 1.4</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa-search"></i>Menu 1.5</a></li>
            </ul>
            <i class="arrows fa fa-chevron-down"></i>
          </li>
          <li><a href="#" class="txtlink"><i class="fa "></i>Menu 2</a></li>
          <li class="children">
            <a href="#" class="txtlink"><i class="fa fa-folder"></i>Menu 3</a>
            <ul class="sub">
              <li class="children">
                <a href="#" class="txtlink"><i class="fa fa fa-search"></i>Menu 3.1</a>
                <ul class="sub">
                  <li><a href="#" class="txtlink"><i class="fa fa-user"></i>Menu 3.1.1</a></li>
                  <li><a href="#" class="txtlink"><i class="fa fa-bookmark-o"></i>Menu 3.1.2</a></li>
                </ul>
                <i class="arrows fa fa-chevron-down"></i>
              </li>
              <li><a href="#" class="txtlink"><i class="fa"></i>Menu 3.2</a></li>
              <li><a href="#" class="txtlink"><i class="fa"></i>Menu 3.3</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa fa-calendar"></i>Menu 3.4</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa fa-search"></i>Menu 3.5</a></li>
            </ul>
            <i class="arrows fa fa-chevron-down"></i>
          </li>
          <li><a href="#" class="txtlink"><i class="fa fa-comments"></i>Menu 4</a></li>
        </ul>
      </div>
    
    </nav>

答案 1 :(得分:1)

首先,努力尝试并提供代码。也就是说,有很多方法可以改善这一点,我没有时间进入,但是已经做了一些改变以弥合这个差距:

  1. 使用变量使代码更高效,更易于阅读。存储$(this)$(this).parent()是代码中的两个必须
  2. 问题的核心是$parent.find('i').hasClass('fa-chevron-down'),它定位了该父级下的所有<i>元素,如果有任何类,那么它将是真的。我很快将此更改为仅查找i.fa-chevron-down,但使用jQuery.children()也可能是更好的选择

  3. 为避免$碰撞,避免使用$(document).ready并使用jQuery(document).ready是一个很好的经验法则。如果你调用命名参数,那么$可以在内部使用;例如.ready(function($){

  4. &#13;
    &#13;
    jQuery(document).ready(function($) {
      $('.children a.txtlink').on("click", function(e) {
        // toggle the icons when the text link is pressed
    
        var $this = $(this),
          $parent = $this.parent(),
          $ul = $parent.find('ul:first');
    
        $ul.toggle(); // toggle the next UL
    
        if ($parent.find('i.fa-chevron-down').length) {
          $parent.find('i.fa-chevron-down').removeClass("fa-chevron-down").addClass("fa-chevron-up");
        } else {
          $parent.find('i.fa-chevron-up').removeClass("fa-chevron-up").addClass("fa-chevron-down");
        }
    
        e.stopPropagation();
        e.preventDefault();
      });
    
      $('.children i.arrows').on("click", function(e) {
        // toggle the icons when the chevron is pressed
        
        var $this = $(this),
          $parent = $this.parent(),
          $ul = $parent.find('ul:first');
    
        $ul.toggle(); // toggle the next UL
    
        if ($this.hasClass("fa-chevron-down")) {
          $this.removeClass("fa-chevron-down").addClass("fa-chevron-up");
        } else {
          $this.removeClass("fa-chevron-up").addClass("fa-chevron-down");
        }
    
        e.stopPropagation();
        e.preventDefault();
      });
    
    
    });
    &#13;
    .navbar_menu {
      background: #222222;
    }
    
    .menu {
      border-top: 1px solid #2D2D2D;
    }
    
    .menu ul {
      padding: 0;
      margin: 0;
    }
    
    .menu li {
      list-style: none;
      position: relative;
    }
    
    .menu li i {
      padding-right: 3px;
    }
    
    .menu a.txtlink {
      color: #ccc;
      display: block;
      font-size: 16px;
      padding: 10px;
      padding-right: 0;
      border-bottom: 1px solid #2D2D2D;
      text-decoration: none;
    }
    
    .menu a.txtlink:hover {
      background: #111111;
      color: #ffffff;
      text-decoration: none;
    }
    
    .menu li.home a.txtlink::before {
      content: '\f015';
      display: inline-block;
      font: normal normal normal 14px/1 FontAwesome;
      font-size: inherit;
      text-rendering: auto;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      transform: none;
    }
    
    .menu ul li {
      position: relative;
    }
    
    .menu ul li.children i.arrows {
      /* needed to show an icon in the mobile menu */
      position: absolute;
      top: 0;
      right: 0;
      padding: 14px;
      border-left: 1px solid #333333;
      margin: 0;
      cursor: pointer;
      display: block;
      color: #CCCCCC;
    }
    
    .menu .sub {
      display: none;
    }
    
    .menu ul li ul li a.txtlink {
      padding-left: 20px;
    }
    
    .menu ul li ul li ul li a.txtlink {
      padding-left: 40px;
    }
    
    .menu i.arrows:hover {
      background-color: #111111;
    }
    
    .menu ul li ul li {
      background-color: #333333;
    }
    &#13;
    <script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
    <nav class="navbar_menu">
    
      <div class="menu">
        <ul>
          <li class="home"><a href="#" class="txtlink">Home</a></li>
          <li class="children">
            <a href="#" class="txtlink"><i class="fa fa-folder"></i>Menu 1</a>
            <ul class="sub">
              <li class="children">
                <a href="#" class="txtlink"><i class="fa fa-search"></i>Menu 1.1</a>
                <ul class="sub">
                  <li><a href="#" class="txtlink"><i class="fa fa-user"></i>Menu 1.1.1</a></li>
                  <li><a href="#" class="txtlink"><i class="fa fa-tag"></i>Menu 1.1.2</a></li>
                </ul>
                <i class="arrows fa fa-chevron-down"></i>
              </li>
              <li><a href="#" class="txtlink">Menu 1.2</a></li>
              <li><a href="#" class="txtlink">Menu 1.3</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa-clock-o"></i>Menu 1.4</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa-search"></i>Menu 1.5</a></li>
            </ul>
            <i class="arrows fa fa-chevron-down"></i>
          </li>
          <li><a href="#" class="txtlink"><i class="fa "></i>Menu 2</a></li>
          <li class="children">
            <a href="#" class="txtlink"><i class="fa fa-folder"></i>Menu 3</a>
            <ul class="sub">
              <li class="children">
                <a href="#" class="txtlink"><i class="fa fa fa-search"></i>Menu 3.1</a>
                <ul class="sub">
                  <li><a href="#" class="txtlink"><i class="fa fa-user"></i>Menu 3.1.1</a></li>
                  <li><a href="#" class="txtlink"><i class="fa fa-bookmark-o"></i>Menu 3.1.2</a></li>
                </ul>
                <i class="arrows fa fa-chevron-down"></i>
              </li>
              <li><a href="#" class="txtlink"><i class="fa"></i>Menu 3.2</a></li>
              <li><a href="#" class="txtlink"><i class="fa"></i>Menu 3.3</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa fa-calendar"></i>Menu 3.4</a></li>
              <li><a href="#" class="txtlink"><i class="fa fa fa-search"></i>Menu 3.5</a></li>
            </ul>
            <i class="arrows fa fa-chevron-down"></i>
          </li>
          <li><a href="#" class="txtlink"><i class="fa fa-comments"></i>Menu 4</a></li>
        </ul>
      </div>
    
    </nav>
    &#13;
    &#13;
    &#13;