开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜