使用javascript将活动类添加到主菜单

时间:2015-06-27 09:28:36

标签: javascript html css menuitem

我已经搜索了很多用于使用javascript将活动类添加到父菜单。

我发现了更多的例子,但没有一个是为我工作,下面是我的代码

HTML

<div id="menu1" class="hmenu">
    <ul>
        <li><a href="#">Item1</a>
            <ul>
                <li><a href="#">SubItem1</a>
                    <ul>
                        <li><a href="#">SubSubItem1</a></li>
                        <li><a href="#">SubSubItem2</a></li>
                    </ul>
                </li>
                <li><a href="#">SubItem2</a> </li>
                <li><a href="#">SubItem3</a>
                    <ul>
                        <li><a href="#">SubSubItem1</a></li>
                        <li><a href="#">SubSubItem2</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li><a href="#">Item2</a></li>
        <li><a href="#">Item3</a>
            <ul>
                <li><a href="#">SubItem1</a>
                    <ul>
                        <li><a href="#">SubSubItem1</a></li>
                        <li><a href="#">SubSubItem2</a></li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
    <br style="clear: left" />
</div>

我的要求是当我点击 SubItem1 时, Item1 SubItem1 都应该有效。

当我点击 SubSubItem1 然后 SubSubItem1 时, SubItem1 Item1 应该是活动的。

表示点击任何链接,然后其所有父链接和同一链接应处于活动状态。

我尝试过这个javascript代码:

$(document).ready(function () {
        $('.hmenu ul li ul').find('li').click(function () {
            //removing the previous selected menu state
            $('.hmenu').find('li.active').removeClass('active');
            //adding the state for this parent menu
            $(this).parents('li').addClass('active');
        });
    });

实际上,我没有使用javascript编码的经验,也无法在code中找出问题。

任何人都可以建议我这样做。

3 个答案:

答案 0 :(得分:4)

问题来自.find('li').click()

当您使用嵌套<li>时,这将导致在您点击子<li>时触发事件两次。这会导致问题。您无法将click()添加到<a>元素吗?

$(document).ready(function () {
    $('.hmenu a').click(function () {
        //removing the previous selected menu state
        $('.hmenu').find('li.active').removeClass('active');
        //adding the state for this parent menu
        $(this).parents("li").addClass('active');

    });
});

它运作得很好:https://jsfiddle.net/6put8tdx/

请注意,由于a锚点,您点击#标签时页面会被置于顶部。如果您想阻止这种情况,可以将事件传递给函数.click(function (event) {...}并在其中添加event.preventDefault

答案 1 :(得分:2)

如果您需要点击目标作为LI元素(而不是Delgan的答案)

您可以使用.not()覆盖目标LI parents,以防止搞乱冒泡事件目标:

$(document).ready(function () {

  $('.hmenu').find('li').click(function(event) {
    event.preventDefault();                   // Prevent page jumps due to anchors
    var $par = $(event.target).parents("li"); // get list of parents
    $(".hmenu .active").not( $par ).removeClass("active");  // not them
    $(this).addClass('active');               // let the event propagation do the work
  });

});

&#13;
&#13;
$(document).ready(function () {

  $('.hmenu').find('li').click(function(event) {
    event.preventDefault(); 
    var $par = $(event.target).parents("li");
    $(".hmenu .active").not($par).removeClass("active");
    $(this).addClass('active');
  });

});
&#13;
.active > a{
  background: gold;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    <div id="menu1" class="hmenu">
      <ul>
        <li><a href="#">Item1</a>
          <ul>
            <li><a href="#">SubItem1</a>
              <ul>
                <li><a href="#">SubSubItem1</a></li>
                <li><a href="#">SubSubItem2</a></li>
              </ul>
            </li>
            <li><a href="#">SubItem2</a> </li>
            <li><a href="#">SubItem3</a>
              <ul>
                <li><a href="#">SubSubItem1</a></li>
                <li><a href="#">SubSubItem2</a></li>
              </ul>
            </li>
          </ul>
        </li>
        <li><a href="#">Item2</a></li>
        <li><a href="#">Item3</a>
          <ul>
            <li><a href="#">SubItem1</a>
              <ul>
                <li><a href="#">SubSubItem1</a></li>
                <li><a href="#">SubSubItem2</a></li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
      <br style="clear: left" />
    </div>
&#13;
&#13;
&#13;

为了更好地理解上述
以下示例开箱即用,单击的一个及其所有LI父项获得"active"类。
为什么?因为事件定位为li,意味着li .hmenu的任何LI - 所以点击已附加到其中任何一个,然后单击 subsub LI,事件将传播到click父项 - 触发相同的$(".hmenu").on("click", "li", function(){ $(this).addClass("active"); // Wow! Event propagation rulez!! }); 行为(此添加类)!

.active

但是我们需要删除现有的$(".hmenu").on("click", "li", function(){ $(".active").removeClass("active"); // triggered on every event bubble :( $(this).addClass("active"); // leaving only the main parent with active class }); ,这里会变得混乱......

setTimeout

由事件起泡并且为父元素触发相同操作时发生的并发性引起的。

防止并发的一种方法是使用1 $(".hmenu").on("click", "li", function(){ $(".active").removeClass("active"); setTimeout(function(){ // Let the previous finish the bubbling mess $(this).addClass("active"); // Yey! all fine! Every LI has the active class }, 1); }); ms:

1ms

但是class TimeGrouper { public int Year { get; set; } public int Month { get; set; } public int Week { get; set; } public int Day { get; set; } } 的超时可以导致视觉&#34;闪烁&#34;的问题。

答案 2 :(得分:-2)

试试这个:

 $(function () {
     $("li a")
       .on("click", function () {
         $(this).toggleClass("active");
         $(this).closest("ul").parent().children("li a").toggleClass("active")
       .parent().parent().parent().children("li a").toggleClass("active");

     });
 });

fiddle

从点击的元素进行遍历。并使用toggleClass()来避免平凡检查hasclass removeClass ...