8

を変更する長いアニメーションがあるとしますwidth:

var myTargetWidth = 500;
$(el).animate( { "width" : myTargetWidth }, 5000 );

アニメーションは非同期であるため、コードは継続します。. . 数秒後、ターゲットwidthをに変更することにしました300。. . この時点でアニメーションはまだ実行中です。. .

実行中のアニメーションで targetWidth を別の値に変更するにはどうすればよいですか?

4

4 に答える 4

5

1 つのオプションはstep、jQueryanimate関数 ( API ) で説明されている関数を使用して、アニメーションの実行中に状態をチェックすることです。

例 JSFiddle : http://jsfiddle.net/GweLA/13/

JS

var myTargetWidth = 500;

$(document).ready(function(){
    $('.sample').animate( { "width" : myTargetWidth },{
        duration : 5000,      
        step: function(now, fx) {
            if($(this).width() > 200){
              myTargetWidth = 300;
              $(this).stop().animate({ "width" : myTargetWidth },1000);
            }
        }
    });
});

CSS

.sample{
    width:20px;
    height:100px;
    background-color:#cccccc;    
}

HTML

<div class="sample">
   width is supposed to be animated till 500 but it stops at 300
</div>

解決策 2:

いくつかの調査の後、アニメーションを制御するために、ステップ関数に渡されるパラメーターstartendプロパティを変更できることがわかりました。fxこの種のアニメーションは滑らかになりますが、あまりきちんとした方法ではありません。

例 JSFiddle : http://jsfiddle.net/GweLA/57/

JS

var myTargetWidth = 500;
var isExecuted = false;
$(document).ready(function(){
    $('.sample').animate( { "width" : myTargetWidth },{
        duration : 5000,
        queue : false,
        step: function(now, fx) {
                 //So that fx.start and fx.end is set only once                
                if($(this).width() > 200 && $(this).width() < 203){
                    if(!isExecuted){
                        fx.start = now-65;
                        fx.end = 300;
                    }
                    isExecuted = true;
                }
              }
    });
}); 
于 2012-11-27T19:23:27.313 に答える
2

.stop()の組み合わせを使用できます-アニメーションを停止します。

:animatedselector-現在の要素がアニメーション化されているかどうかをチェックします。

これを試して

HTML

​&lt;div class="a">

​&lt;/div>

​&lt;button id="check">Check Animation </button>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

Javascript

var myTargetWidth = 300;
var $el = $('.a')
$el.animate({
    "width": myTargetWidth
}, 5000);

$('#check').on('click', function() {
    var newHeight = 300;
    if ($('.a:animated')) {
        $el.stop().animate({
            "height": newHeight
        }, 5000);
    }
});​

フィドルをチェック

于 2012-11-27T19:01:27.487 に答える
0

ここに例を追加しました:

http://jsfiddle.net/Q3ZcQ/

アニメーションの途中で「ここをクリック」要素をクリックしてみてください...

clearQueue()と関数を使用しstop()ます。

CSS #block { width:100px; 高さ: 100px; 背景: 赤; } </p>

HTML

<p>
  <a id="clickme">Click here</a>
</p>

jQuery

$('#clickme').not('.again').on('mouseup',function() {
  $(this).addClass('again');
  $('#block').animate({
    width: '400'
  }, 5000, function() {
    // Animation complete.
  });
});

$('.again').live('mousedown', function() {
    $(this).removeClass('again');
 $('#block').clearQueue().animate({
    width: '200',
  }, 500, function() {
     $('#block').stop(true, false);
  });
});​
<div id="block" />​
于 2012-11-27T19:16:24.233 に答える
0

jquery githubのeffects.jsを見ると、割り当て後に変数を変更する際に問題が発生します

ソース: https://github.com/jquery/jquery/blob/master/src/effects.js

注: .animate からアニメーション (作業馬) への割り当てとオブジェクトの作成に注意してください。

animate: function( prop, speed, easing, callback ) {
    var empty = jQuery.isEmptyObject( prop ),
    optall = jQuery.speed( speed, easing, callback ),
    doAnimation = function() {
        // Operate on a copy of prop so per-property easing won't be lost
        var anim = Animation( this, jQuery.extend( {}, prop ), optall );

        // Empty animations resolve immediately
        if ( empty ) {
           anim.stop( true );
        }
    };

return empty || optall.queue === false ?
this.each( doAnimation ) :
this.queue( optall.queue, doAnimation );
}

//effects.js でアニメーション化

function Animation( elem, properties, options ) {
    var result,
        index = 0,
        length = animationPrefilters.length,
        deferred = jQuery.Deferred().always( function() {
            // don't match elem in the :animated selector
            delete tick.elem;
        }),
        tick = function() {
            var currentTime = fxNow || createFxNow(),
                remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
                // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
                temp = remaining / animation.duration || 0,
                percent = 1 - temp,
                index = 0,
                length = animation.tweens.length;

            for ( ; index < length ; index++ ) {
                animation.tweens[ index ].run( percent );
            }

            deferred.notifyWith( elem, [ animation, percent, remaining ]);

            if ( percent < 1 && length ) {
                return remaining;
            } else {
                deferred.resolveWith( elem, [ animation ] );
                return false;
            }
        },
        animation = deferred.promise({
            elem: elem,
            props: jQuery.extend( {}, properties ),
            opts: jQuery.extend( true, { specialEasing: {} }, options ),
            originalProperties: properties,
            originalOptions: options,
            startTime: fxNow || createFxNow(),
            duration: options.duration,
            tweens: [],
            createTween: function( prop, end ) {
                var tween = jQuery.Tween( elem, animation.opts, prop, end,
                        animation.opts.specialEasing[ prop ] || animation.opts.easing );
                animation.tweens.push( tween );
                return tween;
            },
            stop: function( gotoEnd ) {
                var index = 0,
                    // if we are going to the end, we want to run all the tweens
                    // otherwise we skip this part
                    length = gotoEnd ? animation.tweens.length : 0;

                for ( ; index < length ; index++ ) {
                    animation.tweens[ index ].run( 1 );
                }

                // resolve when we played the last frame
                // otherwise, reject
                if ( gotoEnd ) {
                    deferred.resolveWith( elem, [ animation, gotoEnd ] );
                } else {
                    deferred.rejectWith( elem, [ animation, gotoEnd ] );
                }
                return this;
            }
        }),
        props = animation.props;

    propFilter( props, animation.opts.specialEasing );

    for ( ; index < length ; index++ ) {
        result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
        if ( result ) {
            return result;
        }
    }

    createTweens( animation, props );

    if ( jQuery.isFunction( animation.opts.start ) ) {
        animation.opts.start.call( elem, animation );
    }

    jQuery.fx.timer(
        jQuery.extend( tick, {
            anim: animation,
            queue: animation.opts.queue,
            elem: elem
        })
    );

    // attach callbacks from options
    return animation.progress( animation.opts.progress )
        .done( animation.opts.done, animation.opts.complete )
        .fail( animation.opts.fail )
        .always( animation.opts.always );
}

その結果、クロージャー内の変数にアクセスする見込みがほとんどないため、変更された変数でアニメーションを停止して再キューイングする必要があると思います(誰かが私を修正してください)

于 2012-11-27T19:07:50.597 に答える