如何在jQuery中为同一个div中的多个项目制作动画?

时间:2015-01-26 08:13:49

标签: jquery animation

这是我的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. 鼠标悬停
  2. 上向上滑动,或在我的情况下将动画放大40px h2(标题)
  3. 当h2向上移动后,我想先将宽度从160改为320,然后向左滑动160px
  4. 当我的div向左滑动时,我想显示我的段落。 再看看图像: enter image description here
  5. mouseout 与鼠标悬停相反。有人可以帮我这个吗?

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

2 个答案:

答案 0 :(得分:0)

这有点棘手。 jQuery动画队列适用于动画/停止单个元素。为多个元素创建一个行为良好的队列并不简单。

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

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

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 - 放慢速度以使序列更易于观察。

我担心你自己的解决方案的简单性已经消失,除非你习惯于使用承诺,否则这不会是最明显的解决方案,但你会发现它在快速方面是可靠的小鼠动作。

BTW:之前使用.queue()dequeue()的尝试在实现所需的动画序列方面更为优雅,但实际上很难抑制它。我放弃了,退回到承诺,我明白了。

答案 1 :(得分:0)

最后,我把它搞定了。这是我的答案:     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();
        });

如果你有更好的版本,很乐意接受它并标记它。