Morgan Wilde
Morgan Wilde

Reputation: 17303

Jquery not behaving as expected with .not and .on

I want to prevent two events from being watched for an element (mouseenter and mouseleave to be specific) if that certain element doesn't have a css class defined.

The flow of this system is

  1. On document ready, I add the class .selected to the #menu_top_option_1 element

    $("#menu_top_option_1").addClass("selected");
    
  2. There is a sensor for those two events

    $("#menu_top_option_1").not(".selected").on({
        mouseenter: function(){
            $(this).addClass("highlighted");
        },
        mouseleave: function(){
            $(this).removeClass("highlighted");
        }
    });
    
  3. When there is a click event I add the class .selected to the #menu_top_option_1 element.

    $("#menu_top_option_1").click(function () {
        $("#menu_top_arrow_img").animate({left: position_menu_top_option_1+'px'}, 500);
        $(this).removeClass("highlighted");
        $("#option_wrapper div.option").removeClass("selected");
        $(this).addClass("selected");
    });
    

The problem: this does not work as expected. The elements still have the same hover events as they did before being assigned the .selected even after adding .selected to them. Except for the #menu_top_option_1 element, because I suspect it does have that class added at document ready.

Any suggestions?

Upvotes: 0

Views: 64

Answers (2)

Jasper
Jasper

Reputation: 76003

You should bind the event handler to all of the elements and then inside that event handler, check to see if the current element being clicked has the selected class:

$(function () {
    //bind a click event handler to all of the menu items that:
    //1. removes the `selected` class from the element that currently has it
    //2. applies that class to the element clicked
    //3. removes the `highlighted` class from the current element since it will have it, due to the fact that you have to hover over an element to click it
    $('#option_wrapper').children().on('click', function () {
        $(this).siblings('.selected').removeClass('selected').end().removeClass('highlighted').addClass('selected');

    //bind a mouseenter event handler to the menu items that updates the currently moused-over element only if it doesn't have the `selected` class
    }).on('mouseenter', function () {

        //notice the `!` here, so we are checking for the non-existence of the class in question
        if (!$(this).hasClass('selected')) {
            $(this).addClass('highlighted');
        }

    //bind a mouseleave event handler to the menu items that removes the `highlighted` class
    }).on('mouseleave', function () {
        $(this).removeClass('highlighted');
    });
});
​

Here is a demo: http://jsfiddle.net/g8W4z/

Some documentation:

Upvotes: 3

Steve
Steve

Reputation: 8640

I think the problem stems from the fact that you are attaching the event listeners on document ready. Once they are attached, you never remove them. Therefore the menu options continue to behave exactly as they did on page load.

Upvotes: 1

Related Questions