Вопрос

I have the following code and I can't figure out why the hoverIntent event is firing although I assign the selected-food class to the li element on click.

Here is a jsfiddle: http://jsfiddle.net/7uPcc/2/

Expected behaviour: When a list item is clicked, the selected-food class is assigned to it (works fine) and the hidden div containing ingredients is not shown on hover. I'm trying to achieve this with the .not() method.

Actual behaviour: The hidden div is shown on hover although the hovered item has the selected-food class assigned.

HTML

<ul>
    <li class="food-name">Food 1
        <div class="food-ingredients">
            <ul>
                <li>Ingredient 1</li>
                <li>Ingredient 2</li>
                <li>Ingredient 3</li>
            </ul>
        </div>                    
    </li>
    <li class="food-name">Food 2
        <div class="food-ingredients">
            <ul>
                <li>Ingredient 1</li>
                <li>Ingredient 2</li>
                <li>Ingredient 3</li>
            </ul>
        </div>
    </li>
</ul>

CSS

.food-ingredients {
    display: none;
}

.selected-food {
    color: red;
}

Javascript

$('.food-name').not('.selected-food').hoverIntent({
    over: function() {
        $(this).children('.food-ingredients').show();
    }, 
    out: function() {
        $(this).children('.food-ingredients').hide();
    },
    timeout: 300
});

$('.food-name').click(function() {
    $(this).toggleClass('selected-food');
});

When I test the $('.food-name').not('.selected-food') selector in the console I get the expected result (i.e. list items with the selected-food class are not returned)

Это было полезно?

Решение

The hoverIntent event is bound to the elements on page load. At that time no elements have the class 'selected-food', so all of them trigger the hoverIntent event, even if you later add the 'selected-food' class to them.

Here is a working example:

$('.food-name').hoverIntent({
    over: function() {
        if (!$(this).hasClass('selected-food')) {
            $(this).children('.food-ingredients').show();
        }
    }, 
    out: function() {
        $(this).children('.food-ingredients').hide();
    },
    timeout: 300
});

$('.food-name').click(function() {
    $(this).toggleClass('selected-food');
});

Link to jsfiddle: http://jsfiddle.net/7uPcc/8/

Другие советы

The event handler is being assigned before the class has been added. Changing the class names later will have no effect on this.

This script will check to see if the class exists when the event fires...

$('.food-name').hoverIntent({
    over: function() {
        if ($(this).hasClass("selected-food")) return;
        $(this).children('.food-ingredients').show();
    }, 
    out: function() {
        if ($(this).hasClass("selected-food")) return;
        $(this).children('.food-ingredients').hide();
    },
    timeout: 300
});

$('.food-name').click(function() {
    $(this).toggleClass('selected-food');
});

Here's an update to your fiddle example...

http://jsfiddle.net/7uPcc/11/

Use conditions in your functions:

    $('.food-name').hoverIntent({
        over: function() {
            if(!$(this).hasClass('selected-food')){
                $(this).children('.food-ingredients').show();
            }
        }, 
        out: function() {
            if(!$(this).hasClass('selected-food')){
                $(this).children('.food-ingredients').hide();
            }
        },
        timeout: 300
    });

I think this is what you're looking for:

$('.food-name').hoverIntent({
    over: function() {
        if (!$(this).hasClass('selected-food')) { 
          $(this).children('.food-ingredients').show();
        }
    }, 
    out: function() {
        $(this).children('.food-ingredients').hide();
    },
    timeout: 300
});

$('.food-name').click(function() {
    $(this).toggleClass('selected-food').children('div')
           .toggle(!$(this).hasClass('selected-food'));
});

On hover over, only show the food-ingredients if the current item doesn't have the class selected-food.

In your click handler, toggle the visibility of the food-ingredients based on whether or not you've just added the selected-food class to it.

Here's a fiddle

Because the event is bound to the set of matched elements at the time of running the code ($('.food-name').not('.selected-food').hoverIntent). When you remove the class, the element still got the trigger.

Add a if condition within your hover function or use delegate

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top