简体   繁体   中英

jQuery first element of type click

I am working through an issue where I have a menu that is mutli levels deep. I am trying to get it so that if a first level element is clicked (add class .ubermenu-active ) it will look for any other first level element with that class and remove it.

$('.ubermenu-item-level-0 span').on('click',function() {
    var target = $('.ubermenu-item-level-0');
    $('.ubermenu li.ubermenu-item-level-0').removeClass('ubermenu-active');
    target.parents('.ubermenu li.ubermenu-item-level-0').toggleClass('ubermenu-active');
});

HTML (mock):

<ul class="ubermenu">
    <li class="ubermenu-item-level-0">
        <a class="ubermenu-target">
            <span class="ubermenu-target-title">Level 1</span>
        </a>
        <ul class="ubermenu-submenu">
            <li class="ubermenu-item-level-1">
                <a class="ubermenu-target">
                    <span class="ubermenu-target-title">Level 2</span>
                </a>
            </li>
            <li class="ubermenu-item-level-1">
                <a class="ubermenu-target">
                    <span class="ubermenu-target-title">Level 2</span>
                </a>
                <ul class="ubermenu-submenu">
                    <li class="ubermenu-item-level-2">
                        <a class="ubermenu-target">
                            <span class="ubermenu-target-title">Level 3</span>
                        </a>
                    </li>
                </ul>
            </li>
        </ul>
        <li class="ubermenu-item-level-0">
            <a class="ubermenu-target">
                <span class="ubermenu-target-title">Level 1</span>
            </a>
        </li>
    </li>
</ul>

Right now if any of the sub elements are clicked the parent closes

Currently your target var is selecting all elements with class .ubermenu-item-level-0 , so when you toggle the class you're toggling all parent elements. Your target var should be something relative to the element clicked, like var target = $(this).closest('.ubermenu-item-level-0');

您可以停止事件传播:

event.stopPropagation()

Without seeing the full HTML, I was going to suggest trying this:

$('.ubermenu-item-level-0 span').on('click',function(e) {
       e.stopPropagation();
       var target = $('.ubermenu-item-level-0');
       $('.ubermenu li.ubermenu-item-level-0').removeClass('ubermenu-active');
       target.parents('.ubermenu li.ubermenu-item-level-0').toggleClass('ubermenu-active');
    });

So, your sample HTML isn't what I expected to see . . . specifically, your second <li class="ubermenu-item-level-0" . . . <li class="ubermenu-item-level-0" . . . element is currently showing as a child under the first one, while your description makes it sound like they should be siblings.

For the sake of the solution I'm going to assume that those two li s are supposed to be siblings of each other and that somehow the code got mixed up. :)

So, here's how I would handle it . . .

var sFirstLevelMenuClass = ".ubermenu-item-level-0";
var sActiveMenuClass = "ubermenu-active";
var $firstLevelMenuOptions = $(".ubermenu").find(sFirstLevelMenuClass);

$firstLevelMenuOptions.children("a").children("span").on("click", function() {
    $firstLevelMenuOptions.removeClass(sActiveMenuClass);
    $(this).closest(sFirstLevelMenuClass).addClass(sActiveMenuClass);
});

Basically, I've simplified your logic and fixed one small issue that you had in your jQuery code.


Detailed Explanation

The issue was that when you used $('.ubermenu-item-level-0 span') as your selector for your change event. That translates to "any span element that is a descendant of a ubermenu-item-level-0 element". So, in addition to the spans that are directly under the ubermenu-item-level-0 list items, it was also picking up the ones under the ubermenu-item-level-1 and ubermenu-item-level-2 elements, since they are also descendants.

So, I changed your selector to $firstLevelMenuOptions.children("a").children("span") which translates to "all span s, that are direct children of an a , that is the direct child of an ubermenu-item-level-0 element" ( Note: $firstLevelMenuOptions is set to equal $(".ubermenu").find(".ubermenu-active"); through the logic earlier in the code ). This stops the selector from picking up the lower level spans .

Outside of that and trimming down some of your selectors to be more efficient, the only other thing that I changed was the flow of how the ubermenu-active class is manipulated. In my solution, there are two steps:

  1. Remove ubermenu-active from ALL ubermenu-item-level-0 elements
  2. Add ubermenu-active to the closest ubermenu-item-level-0 element to the span that was clicked (ie, $(this) )

That basically resets the list and then reselects the appropriate menu item to me active.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM