Skip to content
Advertisement

Jquery call function on hover if element is of class A but not class B

I want to call a function when hovering over elements with a specific class attribute, but not another. I feel like the :not selector should work, but it is still firing for all elements of class A.

I have elements with a specific class .sidebar-section, but one of them has another class attribute .show, I want to call a function on hover for class sidebar-section excluding elements that are also of the class show.

    <div class="sidebar-section show" id="one">
        <div class="sidebar-title">Ones</div>
    </div>
    <div class="sidebar-section" id="two">
        <div class="sidebar-title">Twos</div>
    </div>

I want to set up a hover listener for sidebar-section that will fire when hovering over Twos but not over Ones. I have tried $(".sidebar-section:not(.show)").hover() but for some reason this is not working, since it still fires for all sidebar-sections.

$(".sidebar-section:not(.show)").hover(
    function () {
        toggleSection(this.id);
    },
    function () {
        toggleSection(this.id);
    }
);

Thanks to @CBroe’s suggestion I’ve edited the code by moving the check for the show class into hover handler. This accomplished the main part of my question since the shown element no longer collapses when hovered over. But this collapses the element when I leave.

To fix this I added a mouseleave event handler with a function to toggle #one once the mouse is no longer on the sidebar, but the function is never called. Why is the mouseleave of the sidebar-container not executing?

//Contents are hidden unless section is selected
$(function () {
    $(".sidebar-contents").hide();
    toggleSection("one");
});

$(".sidebar-section").hover(
    function () {
        if(!$(this).hasClass("show")){
            toggleSection(this.id);
        }
    },
    function () {
        toggleSection(this.id);
    }
);

$("#sidebar-container").mouseleave(
    function () {
        toggleSection("one");
    }
);

//toggles collapsed/expanded view of sidebar sections
function toggleSection(name) {
    $("#" + name).children('.sidebar-contents').toggle();
    $("#" + name).children('.sidebar-title').toggle();
    $("#" + name).toggleClass('show');
}
#sidebar-container {
    display: flex;
    height: 100%;
}

.sidebar-section {
    background-color: blue;
    writing-mode: vertical-lr;
}

.sidebar-section.show {
    background-color: yellow;
    writing-mode: horizontal-tb;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sidebar-container">
    <div class="sidebar-section" id="one">
        <div class="sidebar-title">Ones</div>
        <ul class="sidebar-contents">
            <li>Item 1</li>
        </ul>
    </div>
    <div class="sidebar-section" id="two">
        <div class="sidebar-title">Twos</div>
        <ul class="sidebar-contents">
            <li>Item 2</li>
        </ul>
    </div>
</div>

Advertisement

Answer

The problem is with your toggleSection function. When you hover over an item, you are toggling the show class. That is why, your selector doesn’t work. Can you update your hover function with this:

$(".sidebar-section").hover(
    function () {
        $(this).children('.sidebar-contents').show();
        $(this).children('.sidebar-title').hide();
        $(this).addClass('show');
    },
    function () {
        $(this).children('.sidebar-contents').hide();
        $(this).children('.sidebar-title').show();
        $(this).removeClass('show');
    }
);
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement