jQuery 中的动画问题和大量 stop() 调用

Posted

技术标签:

【中文标题】jQuery 中的动画问题和大量 stop() 调用【英文标题】:Problem with animations and a lot of stop() calls in jQuery 【发布时间】:2011-06-30 11:48:24 【问题描述】:

这是我想要做的: 我有几个带有价格的 div,还有一个固定最小值的滑块,我可以在其中设置最高价格。这样我就可以过滤 div,所以只会显示价格在滑块范围内的 div。

没有动画也没问题,只是 hide() 和 show(),但我正在努力做到流畅。

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'+vehicles[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>

这是我的代码,这是我的问题:将滑块推到一侧或点时,它可以正常工作,但是 f.e.将其推至 0 欧元并立即回到 700 欧元(当 hide() 动画仍在运行时),所有 div 都被隐藏(但它们的 data('visible') 设置为 true)。您可以在此处查看我的运行代码:http://work4.bywulf.de/index.php?page=Vehicles 只需将滑块快速向左滑动并返回右侧即可。

看来 stop() 方法没有正确停止他们当前的“隐藏”动画,并且“显示”动画没有播放。

现在我做错了什么还是有另一种方法来隐藏动画元素,但中途停止它们并再次完全显示它们?

我希望你知道我的意思和我想要做什么,谢谢你的帮助。

(jQuery 1.5, jQueryUI 1.8.9)

--武尔夫

【问题讨论】:

你在什么浏览器看到你描述的效果? Firefox 3.6.13 和 Chromium 最新构建 你试过.stop(true,true)吗? 刚试过,同样的问题... 现在设置我自己的动画代码,仍然有一些怪癖,例如滚动到底部时页面闪烁并且页面高度减小。还在想,为什么上面的代码行不通。 【参考方案1】:

问题解决了,只是做了一个自己的 .animation()。我认为问题在于,show() 和 hide() 看到项目的原样,当项目仅显示 50% 时,它会很困难。 .animation() 将从 50% 开始并在给定尺寸结束。所以我具体做的是:

首先我初始化了容器,所以高度被保存了:

$(selector).data('visible',true)
  .data('initialHeight',$(selector).height())
  .data('initialOuterHeight',$(selector).outerHeight())
  .data('initialMarginBottom',$(selector).css('marginBottom'));

然后,当需要动画时,执行这部分:

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);
  

还是谢谢你的建议。

【讨论】:

非常感谢这项技术;)它拯救了我的一天【参考方案2】:

我建议:

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();

或者可以用上滑/下滑来获得不同的效果:

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() 和 hide() 看起来确实有问题

【讨论】:

【参考方案3】:

您可能遇到了重入问题。

当另一个事件触发代码再次运行时,代码已经在运行。 你可以试试这样的:

    function Sample(event, ui)
    
        var running;  // prevent re-entrant code

        if (running == true)
            return;
        else
            running = true;

        // a bunch of code

        running = false;
    

当用户最终放开滑块时,您仍然需要一种方法来确保视图与滑块位置同步。

【讨论】:

也想过这样的事情,但也没有解决问题。对于同步问题,我只是用 setInterval 设置了一个函数,让它每 100 毫秒检查一次所有未动画容器的数据('可见')和真实状态匹配......

以上是关于jQuery 中的动画问题和大量 stop() 调用的主要内容,如果未能解决你的问题,请参考以下文章

JQuery动画

jQuery 停止动画-jQuery stop()

jquery中stop停止动画笔记

jQuery 调用 CSS3 版本的 stop(true,false) 和事件动画?

jQuery中停止动画stop

jquery.stop()停止动画