如何为 jQuery 中同一 div 中的 1 个以上项目制作动画?

How to animate more than 1 item from the same div in jQuery?

这是我的 html 代码:

<div class ="row respect-row">
    <div class="col-xs-6 myclass1">
        <h2 id ="respect-hover">MY HEADER</h2>
        <p style="display:none">paragraph text paragraph text paragraph text paragraph text paragraph text</p>
    </div>
</div>

这是我的js代码:

$(".respect-row").mouseover(function(){
            $(this).find("h2").animate({
                'marginTop' : "-=40px"
            },200);
            $(this).find("p").show(function(){
                $(this).find("p").animate({
                '   marginTop' : "-=40px"
                },200);
            });
            // $(this).find(".col-xs-6").animate({ "left": "+=160px" }, "slow" );
             $(this).css("width","320");
        });
        $(".respect-row").mouseout(function(){
            $(this).find("h2").animate({
                'marginTop' : "+=40px"
            });
            $(this).find("p").hide();
            $(this).css("width","160");
        });

我想达到的目标:

  1. mouseover
  2. 上向上滑动,或者在我的例子中将 h2 (header) 向上滑动 40px
  3. 当h2向上移动后,我想先把宽度从160改成320,然后向左滑动160px
  4. 当我的 div 向左滑动时,我想显示我的段落。 也看看图像:

mouseout 与 mouseover 发生的情况相反。有人可以帮我解决这个问题吗?

更新http://jsfiddle.net/z468j1a4/1/

这有点棘手。 jQuery 动画队列围绕 animating/stopping 单个元素。为多个元素制作一个行为良好的队列并不简单。

"well behaved" 是什么意思?您想要的行为可以通过多种方式实现 see Kevin B's answer here。然而,停止包含多个元素的动画队列并不是那么简单。这是快速 mouseenter-mouseleave 操作的问题。在您自己的解决方案中尝试一下,您会发现动画会变得混乱。

可能有几种方法可以解决这个问题。这是一个涉及 promise 链的机制,如果先前的动画链仍在进行中,则可以杀死它们。

var t = 700;
$(".respect-row").on('mouseenter', function () {
    //In case an earlier animation is still in progress ...

    //...(i) withdraw permission for any earlier animation to continue
    var $this = $(this).data('continue', false);

    //...(ii) stop everything.
    $this.stop(true, true);
    var $h2 = $this.find("h2").stop(true, true);
    var $p = $this.find("p").stop(true, true);

    // Animations, each defined as a named function that returns a promise
    function anim1() {
        if($this.data('continue')) {
            return $h2.animate({
                'marginTop': '0px',
                'marginBottom': '20px'
            }, t).promise();//allow the rest of the animation chain to continue
        } else {
            return $.Deferred().reject().promise();//suppress the rest of the animation chain
        }
    }
    function anim2() {
        if($this.data('continue')) {
            return $this.animate({
                'width': '320px'
            }, t).promise();//allow the rest of the animation chain to continue
        } else {
            return $.Deferred().reject().promise();//suppress the rest of the animation chain
        }
    }
    function anim3() {
        if($this.data('continue')) {
            return $p.fadeIn(t).promise();//allow the rest of the animation chain to continue
        } else {
            return $.Deferred().reject().promise();//suppress the rest of the animation chain
        }
    }

    //Invoke forward animations with `continue` set to true
    $this.data('continue', true);
    anim1().then(anim2).then(anim3);
});
$(".respect-row").on('mouseleave', function revert() {
    //In case an earlier animation is still in progress ...

    //...(i) withdraw permission for any earlier animation to continue
    var $this = $(this).data('continue', false);

    //...(ii) and stop everything.
    $this.stop(true, true);
    var $h2 = $this.find("h2").stop(true, true);
    var $p = $this.find("p").stop(true, true);

    // Animations, each defined as a named function that returns a promise
    function anim1() {
        if($this.data('continue')) {
            return $h2.animate({
                'marginTop': '20px',
                'marginBottom': '0px'
            }, t).promise();//allow the rest of the animation chain to continue
        } else {
            return $.Deferred().reject().promise();//suppress the rest of the animation chain
        }
    }
    function anim2() {
        if($this.data('continue')) {
            return $this.animate({
                'width': '160px'
            }, t).promise();//allow the rest of the animation chain to continue
        } else {
            return $.Deferred().reject().promise();//suppress the rest of the animation chain
        }
    }
    function anim3() {
        if($this.data('continue')) {
            return $p.fadeOut(t).promise();//allow the rest of the animation chain to continue
        } else {
            return $.Deferred().reject().promise();//suppress the rest of the animation chain
        }
    }

    //invoke reverse animations with `continue` set to true
    $this.data('continue', true);
    anim3().then(anim2).then(anim1);
});

DEMO - 放慢速度以使序列更易于观察。

恐怕您自己的解决方案的简单性已经消失,除非您习惯于使用 promise,否则这不会是最明显的解决方案,但您会发现它在快速鼠标移动方面是可靠的.

顺便说一句:之前尝试使用 .queue()dequeue() 在实现所需的动画序列方面更优雅,但事实证明很难抑制它。我放弃了,退回到了诺言,我明白了。

终于,我成功了。这是我的答案: http://jsfiddle.net/z468j1a4/2/

$(".respect-row").mouseenter(function(){

            $(this).find("h2").stop(true, true).animate({
                'marginTop' : "-=60px"
            },200);

            $(this).stop(true, false).animate({ width: "320px" });
            //$(this).find("p").show();
            $(this).find("p").fadeIn( 1200 );
        });
        $(".respect-row").mouseleave(function(){
            $(this).find("h2").stop(true, true).animate({
                'marginTop' : "+=60px"
            },200);
            $(this).stop(true, false).animate({ width: "160px" });
            $(this).find("p").hide();
        });

如有更好的版本,欢迎采纳并标记