jQuery: fade in/out + animate elements

陌路散爱 提交于 2019-12-06 02:23:50

The core cause of your issue is that you need a call to .siblings().stop(), in addition to the $(this).stop() (which you already have).

After you fix that, you'll see a new issue, where your captions initially work correctly, but then begin to fade in only partially once they've been moused-over repeatedly (and eventually, they'll disappear completely until you reload the page). This is due to the way .fadeIn() works when combined with .fadeOut() -- fadeIn() doesn't always fade-in to opacity:1 -- instead, it fades-in to whatever opacity was applied at the time fadeOut() was called previously.

To get around this, you can use animate({opacity:1},'slow') instead of fadeIn('slow') -- or you can use the more concise (and clearer) .fadeTo('slow',1) (docs). (note, the parameter order is different on fadeTo, as compared to the other animation functions - the duration comes first, then the value you want to fade to).

Of course, you could also use fadeTo() in place of your other opacity animation --though there is certainly nothing wrong with using animate() as you've shown -- the two are equivalent. (of course, you would need to se animate() if you want to manipulate multiple css properties at the same time.)

When it all comes together, it might look something like this:

$(function() {
    $('.image').each(function() {
        $(this).hover( function() {
            $(this).stop().fadeTo('slow',0.3)
                .siblings().stop().fadeTo('slow',1);
        }, function() {
            $(this).stop().fadeTo('slow',1)
                .siblings().stop().fadeTo('slow',0);
        });
    });
});

You can see this code in action at jsFiddle: http://jsfiddle.net/coltrane/XstpE/
(note: that example depends on the hosted resources that go with the original post above, so it won't work if those get moved or become otherwise unavailable).


Also note: In the example above, I have included the use of .each() as you did in your original example, but I want to point out that it's really not necessary.

The following is equivalent (and would usually be considered "better" jQuery technique):

$(function() {
    $('.image').hover(function() {
        $(this).stop().fadeTo('slow', 0.3)
            .siblings().stop().fadeTo('slow', 1);
    }, function() {
        $(this).stop().fadeTo('slow', 1)
            .siblings().stop().fadeTo('slow', 0);
    });
});

When you apply an event handler to a multi-element set, jQuery automatically binds the same handler on every element in the set. (I've updated my example at jsFiddle (linked above) to show the code without the each()).


Edit

The OP points out that hovering over the caption (which sits on top of the image) causes the mouseleave handler to trigger, thus resulting in the roll-out action being performed. The desired behavior is to have the caption not trigger the rollout.

This issue happens because the caption "shadows" the image, and the hover() is applied to the image. When the mouse rolls over the caption it's no longer on the image (it's on the caption) so the browser fires a mouseleave on the image. This same situation can give rise to all sorts of other subtle problems too -- especially as you add more complex content.

To solve this, I recommend that you simply apply hover() one level up (to the container that holds the image and the caption), instead of applying it to the image directly. In this case that container is $('.entry'). The code would change like this:

$(function() {
    $('.entry').hover(function() {
        $('.image',this).stop().fadeTo('slow', 0.3)
            .siblings().stop().fadeTo('slow', 1);
    }, function() {
        $('.image',this).stop().fadeTo('slow', 1)
            .siblings().stop().fadeTo('slow', 0);
    });
});

here is a new version of the jsFiddle

Not sure how long 'slow' paramater means in your animate functions. Try tweaking that to 'fast' or even provide a numeric value in milliseconds and see if that would help.

To stop animation on an element when your mouse leaves it:

$('.image').mouseleave(function() {
    $(this).stop();
});

Try using mouseenter() and mouseleave() instead of hover().

$(function(){
    $('.image').each(function() {
        $(this).mouseenter( function() {
            $(this).stop().animate({ opacity: 0.3 }, 'slow');
            $(this).siblings().fadeIn('slow');
        })
        .mouseleave( function() {
            $(this).stop().animate({ opacity: 1 }, 'slow');
            $(this).siblings().fadeOut('slow');
        });
    });
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!