Zach Nicodemous
Zach Nicodemous

Reputation: 9487

jQuery .append once at a time only (currently occurs multiple times)

I am having a problem with an append. I am using "mouseenter" and "mouseleave" instead of onhover so that the append isn't happening a million times, however I am still having an issue with people entering and leaving their mouse multiplte times on the div.

To see the issue, please goto http://mercury-consulting.theportlandco.com/ and put your mouseover "cloud based" in the banner about 20% of the way down the page. If you then move your mouse away and then back over again several times in succession, the append occurs multiple times creating layers and layers.

This is an example of my code:

$("#cloud1").live("mouseenter", function() {
$(this).append('<div class="cloud1" style="display:none"><img src="http://mercury-consulting.theportlandco.com/wp-content/uploads/2010/10/1.png" width="470" height="270"/></div>')
.find('div.cloud1').show("slide", { direction: "down" }, 1100); 
});

$("#cloud1").live("mouseleave", function() {
$(".cloud1").hide("slide", { direction: "down" }, 1100, function() {
    $(this).remove();
});
});

Upvotes: 0

Views: 1998

Answers (4)

Niloct
Niloct

Reputation: 9995

Your code still has problems. Check the screenshot I took after you implemented stop() in your site:

enter image description here

Reproduce the bug by keeping mousing over and out the activation div ('Cloud based' for example) a couple of times before the show animation ends, then just stop the mouse over 'Cloud based'.

What others said (verifying if there is already a .cloud1 layer there) can be integrated in your solution with append(function (idx,html)) syntax (doc is here):

$("#cloud1").bind("mouseenter", function() {
    $("#cloud1").append(function(idx, html) {
        if ($(html).find('.cloud1').size() == 0) {
            return '<div class="cloud1" style="display:none"><img src="http://mercury-consulting.theportlandco.com/wp-content/uploads/2010/10/1.png" width="470" height="270"/></div>'; 
        }
    }).find('.cloud1').stop().show("slide", { direction: "down" }, 1100);
});

Finally, I used bind instead of live because:

This method (live()) is a variation on the basic .bind() method for attaching event handlers to elements. When .bind() is called, the elements that the jQuery object refers to get the handler attached; elements that get introduced later do not, so they would require another .bind() call.

Since you have only one #cloud1, and no others are introduced later, you don't need live().

Upvotes: 0

Gary Green
Gary Green

Reputation: 22395

Use .stop(true, true) on the object being animated to cancel the preceding animation.


Edit: actually looking at your code you could do something allow the following:

$('#cloud1, #cloud2, #cloud3').hover(function() {
    var id =  $(this).attr('id');

    // If a div isn't already available/animating, then create it
    if (!$('div.' + id).length)
    {
        // Create and show the div
    }
  }, function() {
    // slide the div down
  }
);

Upvotes: 2

eKek0
eKek0

Reputation: 23289

You could have a flag and verify if it is turned off, and if so, then append the layer and turn the flag on; else, don't append the layer.

Upvotes: 0

Bruce Aldridge
Bruce Aldridge

Reputation: 2937

try adding .stop() before the .show() and .hide() it will stop the animation

Upvotes: 2

Related Questions