Problem with animations and a lot of stop() calls in jQuery
here is what I'm trying to do: I have a few div's with prices in them, and a slider with fixed minimum where I can set the maximum price. With that I can filter the divs, so only the div's with prices in the slider range will be displayed.
Without animation it would be no problem, just hide() and show(), but I'm trying to do it smooth.
vehicles[0] = { id: 1, price: 100 };
vehicles[1] = { id: 2, price: 250 };
vehicles[2] = { id: 3, price: 700 };
vehicles[3] = { id: 4, price: 300 };
...
slide: function(event, ui) {
for (i = 0; i < vehicles.length; i++) {
if (vehicles[i].price > ui.value && $('#vehicle'+vehicle开发者_C百科s[i].id).data('visible') == true) {
$('#vehicle'+vehicles[i].id).data('visible',false).stop(true).hide('blind',500);
}
if (vehicles[i].price <= ui.value && $('#vehicle'+vehicles[i].id).data('visible') == false) {
$('#vehicle'+vehicles[i].id).data('visible',true).stop(true).show('blind',500);
}
}
}
...
<div id="vehicle1">100€</div>
<div id="vehicle1">250€</div>
<div id="vehicle1">700€</div>
<div id="vehicle1">300€</div>
That's my code and here is my problem: When pushing the slider to one side or point, it works fine, but f.e. pushing it to 0€ and immediately back to 700€ (while the hide() animation is still running), all divs are hidden (but their data('visible') is set to true). You can see my running code here: http://work4.bywulf.de/index.php?page=Vehicles Just slide the slider fast to the left and back to the right.
It looks like the stop() method is not correctly stopping their current "hide" animation, and the "show" animation is not playing.
Now what am I doing wrong or is there another way to hide elements animated, but stop them half way and show them again completely?
I hope you know what I mean and what I'm trying to do, thank you for your help.
(jQuery 1.5, jQueryUI 1.8.9)
--Wulf
Problem solved, just did an own .animation(). I think the problem was, that show() and hide() see the item as it is, and when the item is shown only 50%, it struggles. .animation() will start at the 50% and end at the given dimentions. So what I did in detail was:
First i initialized the container, so the height is saved:
$(selector).data('visible',true)
.data('initialHeight',$(selector).height())
.data('initialOuterHeight',$(selector).outerHeight())
.data('initialMarginBottom',$(selector).css('marginBottom'));
Then, when animation was needed, this part is executed:
function startAnimation(selector, show, duration) {
$(selector).data('visible',show).stop(true);
if (show) {
$(selector).animate({
height: $(selector).data('initialHeight'),
opacity: 1 ,
marginTop: 0,
marginBottom: $(selector).data('initialMarginBottom')
}, duration);
} else {
$(selector).animate({
height: 0,
opacity: 0 ,
marginTop: $(selector).data('initialHeight') - $(selector).data('initialOuterHeight'),
marginBottom: 0
}, duration);
}
}
Thanks for your advice anyway.
I would propose:
if ((vehicles[i].price > priceRange || search == false || (category > 0 && vehicles[i].category != category) || ($('#availability').is(':checked') && vehicles[i].availability != 0)) && $('#vehicle'+vehicles[i].id).data('visible') == true) {
$('#vehicle'+vehicles[i].id).data('visible',false).stop(true, true).fadeOut(function(){$(this).hide()});
}
if (vehicles[i].price <= priceRange && search == true && (category == 0 || vehicles[i].category == category) && (!$('#availability').is(':checked') || vehicles[i].availability == 0) && $('#vehicle'+vehicles[i].id).data('visible') == false) {
$('#vehicle'+vehicles[i].id).data('visible',true).stop(true, true).show().fadeIn();
}
Or maybe slideUp/slideDown for a different effect:
if ((vehicles[i].price > priceRange || search == false || (category > 0 && vehicles[i].category != category) || ($('#availability').is(':checked') && vehicles[i].availability != 0)) && $('#vehicle'+vehicles[i].id).data('visible') == true) {
$('#vehicle'+vehicles[i].id).data('visible',false).stop(true, true).slideUp();
}
if (vehicles[i].price <= priceRange && search == true && (category == 0 || vehicles[i].category == category) && (!$('#availability').is(':checked') || vehicles[i].availability == 0) && $('#vehicle'+vehicles[i].id).data('visible') == false) {
$('#vehicle'+vehicles[i].id).data('visible',true).stop(true, true).slideDown();
}
show() and hide() seems buggy indeed
You might be experiencing a re-entrancy problem.
The code is already running when another event triggers it to run again. You could try something like this:
function Sample(event, ui)
{
var running; // prevent re-entrant code
if (running == true)
return;
else
running = true;
// a bunch of code
running = false;
}
You would still need a way to make sure the view is synced to the slider position when the user finally lets go of the slider.
精彩评论