这一系列动画的Jquery奇怪行为

Posted

技术标签:

【中文标题】这一系列动画的Jquery奇怪行为【英文标题】:Jquery weird behaviour with this chain of animations 【发布时间】:2014-01-06 01:15:37 【问题描述】:

现在我的 jQuery 动画集遇到了一个非常奇怪的问题。

我尝试了多种方法,但所有方法都给我带来了奇怪的错误。

我为我的例子做了一个 jsfiddle。请检查 console.log 并尝试查看 html 中的动画,它的行为很奇怪。

我有一个菜单,它首先通过淡出里面的文本来关闭一个框,然后打开另一个框并一次淡出每一行文本。

我试图阻止在动画仍在播放时单击菜单的另一个元素的可能性。

我也尝试将.promise().done(function()... 与 each 函数一起使用,但没有奏效。

http://jsfiddle.net/XpJud/

我的 js 文件

$(document).ready(function()

var ongoing=false;
var selected="one";

$("ul li").click(function()

console.log("ongoing : " +ongoing);

if($(this).index() == 1 && selected != "two" && !ongoing )
  console.log("clicked two and in");
  console.log(ongoing);
ongoing=true;
    var text=$("ul li:nth-child(1)").text();
console.log(text);    

    $("."+selected+" div").animate("opacity": 0,1000,function()
    $("."+selected).animate('width': '0px',1000,function()
        $("."+selected).hide();
        $(".extra").animate("color": "blue",1000);
        $("."+text).show().animate('width': '800px',1000,function()
                    selected=text;
                    $("."+selected+" div").each(function(i) 
                     $(this).delay(i*2000).animate("opacity":                   1,2000,function()
                    console.log(i + " is finished");
                    if(i == 2)
                      ongoing=false; 
                    
                   );      
                );


        ); 
  );
);




  else if($(this).index() == 2 && selected != "three" && !ongoing)
  console.log("clicked about and in");
   console.log(ongoing);
ongoing=true;
var text=$("ul li:nth-child(2)").text();
console.log(text);    

$("."+selected+" div").animate("opacity": 0,1000,function()
      $("."+selected).animate('width': '0px',1000,function()
            $("."+selected).hide();
            $(".extra").animate("color": "red",1000);
            $("."+text).show().animate('width': '800px',1000,function()
                  selected=text;
                  $("."+selected+" div").each(function(i) 
                        $(this).delay(i*2000).animate("opacity": 1,2000,function()
                          console.log(i + " is finished");
                          if(i == 2)
                            ongoing=false; 
                          
                        );
                  );
          );
      );
    );

  


);

);

我的 html 文件

    <div class='extra'> Hi</div>

<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>

    <div id="content">

        <div class='one'>

            <div class='one-1'>test test test test</div><br>
            <div class='one-2'>test test test test</div><br>
            <div class='one-3'>test test test test</div><br>

        </div>

        <div class='two'>


            <div class='two-1'>test test test test</div><br>
            <div class='two-2'>test test test test</div><br>
            <div class='two-3'>test test test test</div><br>

        </div>


        <div class='three'>


            <div class='three-1'>test test test test</div><br>
            <div class='three-2'>test test test test</div><br>
            <div class='three-3'>test test test test</div><br>

        </div>  
  </div>

我的 css 文件

ul li

display:inline-block;
background: red;
cursor: pointer;



#content

width:100%;


.three

  margin: 0 auto;

  width: 0px;
  display: none;
  height: 360px;

  text-align: center;

background: #EEE836;

font-size: 50px;
  margin-bottom: 180px;


.two

  margin: 0 auto;

  width: 0px;
  display: none;
  height: 360px;

  text-align: center;

background: blue;

font-size: 50px;

  margin-bottom: 180px;


.one

  margin: 0 auto;

  width: 800px;
  margin-bottom: -180px;
  height: 360px;
  background: white;
  text-align: center;

background: red;

font-size: 50px;




【问题讨论】:

请将您的代码包含在问题中。如果 jsFiddle 出现故障,或者由于某种原因您的小提琴被移动/移除/修改,那么这个问题将毫无意义。 我添加了我的文件,请不要为此投反对票吗? 投反对票的不是我,肯定是其他人。 【参考方案1】:

(1) 当您一次为多个元素设置动画时,您希望回调仅在最后一个动画完成后被调用一次。

要做到这一点,您需要具备以下条件:

$("."+selected+" div").animate("opacity": 0,1000,function()

你可以改成:

$("."+selected+" div").animate("opacity": 0,1000).promise().done(function()

我从 this *** question 那里得到了这项技术。

(2) 在你淡入某些东西之前,你必须首先确保它以淡出的方式开始。同样,在显示元素然后增加其宽度之前,您必须确保它的宽度首先为 0。这些更改可以使用 .css() 函数进行,并且应该在调用 .show() 之前执行。

例如,你有:

$("."+text).show().animate('width': '800px'...

你应该有:

$("."+text).css('width': '0px').show().animate('width': '800px'...

(3) 与使用 .delay() 的技术(尽管更简单)对元素列表按顺序设置动画不同,以下技术提供了更好的结果:

var i = 0;
(function() 
    var $el = $($elements[i++] || []);
    if ($el.length > 0) 
        $el.animate( opacity: 1 , 2000, arguments.callee);  
     else 
        // Perform final tasks.
    
)();

我采用了这种技术from here。

DEMO ON JSFIDDLE

【讨论】:

非常感谢!有史以来最好的答案。感谢您为我的代码制作了一个更简单、更聪明、更简洁的版本。

以上是关于这一系列动画的Jquery奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 奇怪的动画行为与 systemImage

UICollectionView(插入和删除项目)的奇怪动画行为[关闭]

使用 Swift 4 和 UIView 的奇怪动画行为

UIScrollView setContentOffset:动画:奇怪的行为

不同Android版本上的奇怪行为Constraintlayout动画

UINavigationController pushViewController:animated: 表现出奇怪的动画行为