0

setTimeoutとを使用する単純なfadeIn/fadeOutループアニメーションを作成していますclearTimeout。これまでの私のコードは次のとおりです。

HTML:

<p><span>loading...</span></p>
<a href="#" id="btn">STOP</a>

Javascript(jQuery1.9.1):

var _timer;
var _timerArr = [];

var loaderBlink = function() {
    $('p').find('span').fadeTo(200,.4).fadeTo(200,1,function() {
        _timer = setTimeout(function() { loaderBlink() }, 200);
        _timerArr.push(_timer);
        //console.log('loading...');
    });
};

var clearTimer = function() {
    $.each(_timerArr, function(i,val) {
        clearTimeout(val);
        console.log(val);
    });

    $('#btn').remove();
    $('p').fadeOut('fast');

    return false;
};

$('#btn').on('click', function() {
    clearTimer();
});

loaderBlink();

デモ:http://jsfiddle.net/nori2tae/MW9E8/

問題は、後で[停止]ボタンをクリックしてすべてのタイマーをクリアするためにすべてのタイマーを配列にプッシュしても、タイマーが停止せずに続行する場合があることです。

setTimeoutおそらく、との概念を完全には理解していませんclearTimeout。これに対する解決策が必要であり、これら2つの機能を理解するのに役立ちます。

4

4 に答える 4

2

setIntevallのバージョンは次のとおりです。

編集:それはうまく機能しますが、関数loaderBlink();でタイマーをラップする必要があります。繰り返しますが、誤って削除しましたが、まだコーヒーが足りません。

var _timer;

_timer = setInterval(function () {
            $('p').find('span').fadeTo(200,.4).fadeTo(200,1);
            console.log('loading...');
        }, 400);


var clearTimer = function() {
    clearInterval(_timer);

    $('#btn').remove();
    $('p').fadeOut('fast');

    return false;
};

$('#btn').on('click', function() {
    clearTimer();
});

http://jsfiddle.net/XHUTV/2/

于 2013-03-24T10:32:35.057 に答える
1

配列内のすべてのタイマーへの参照を保存することはあまり意味がありません。タイマーは連続して実行されないため、単一の配列に最新のタイマーのみを保存するだけで十分です。最後のものを停止するだけで、他のすべてはすでに停止しています。

アニメーションの実行中にクリックしてもタイマーが停止しないのではないかと思います。アニメーションキューはアニメーションが停止したときにのみタイマーを開始するため、ボタンはまだ開始されていないタイマーを除くすべてのタイマーを停止します。

とにかく、これは実際にはタイマーなしで作成する方が簡単で信頼性が高いでしょう。

var blink = true;

var loaderBlink = function() {
    if( blink ) {
        $('p').find('span').delay( 200 ).fadeTo(200,.4).fadeTo(200,1,function() {
            loaderBlink();
            console.log('loading...');
        });
    }
};

$('#btn').on('click', function() {    
    blink = false;
    $(this).remove();
    $('p').stop().fadeOut('fast');

    return false;
});

loaderBlink();

操作は元のコードとは少し異なります。200ミリ秒の遅延は、アニメーションループの後ではなく、開始時ですが、問題はないと思います。.stop()ループが再開しないことを確認します。

デモ: http: //jsfiddle.net/WAprd/17/

于 2013-03-24T10:28:39.947 に答える
1

この問題へのアプローチは少し間違っています-時間を200msで定義したように-この時間は非常に短い時間であり、コードが反応する前に次のタイマーが進むので、時々動作しますそうではありません。また、setTimeoutは(setIntervalではなく)1回だけ発生するため、すべてのinterval_idを配列に保存しても意味がありません。あなたがする必要があるのは、フラグを使用して、単一のタイマーIDをオフにすることです:http: //jsfiddle.net/MW9E8/2/

var _timer;
var _timerArr = [];
var fading;

var loaderBlink = function() {
    if(fading){
        $('p').find('span').fadeTo(200,.4).fadeTo(200,1,function() {
            interval_id = setTimeout(function() { loaderBlink() }, 200);
           // _timerArr.push(_timer);
            console.log('loading...');
        });
    }
};

var clearTimer = function() {
    /*
    $.each(_timerArr, function(i,val) {

        console.log(val);
    });
    */    
    clearTimeout(interval_id);
    fading = false;

   // $('#btn').remove();
   // $('p').fadeOut('fast');

    return false;
};

$('#btn').on('click', function() {
    clearTimer();
});

fading = true;
loaderBlink();
于 2013-03-24T10:33:58.783 に答える
1

アニメーションにjQueryを使用している場合は、他のすべてにjQueryを使用し続けることをお勧めします...混合する必要はありませsetIntervalssetTimeouts

フィドル

http://jsfiddle.net/QNMkp/

マークアップ

<span id="loading">Loading...</span>

<button id="stop">Stop!</button>

js

$(function(){

    var fadeLoading;

    (fadeLoading = function(){
        $('#loading:not(.stopped)')
            .fadeTo(200,0.4)
            .fadeTo(200,1, fadeLoading) /// you can just loop this
        ;
    })();

    $('#stop').click(function(){
        $('#loading')
            .addClass('stopped') /// add a class to stop new fade starting
            .stop() /// stop existing animations
            .fadeTo(200,1) /// fade loading up to 100%
        ;
    });

});
于 2013-03-24T10:48:23.740 に答える