0

ユーザーがクリックすると、要素がフェードアニメーションで表示および非表示になるようにしようとしています。私はこれを機能させていますが、ユーザーがすばやく連続して 2 回クリックした場合、またはアニメーションが終了する前に問題が発生しました。問題が実行ループやイベントやアニメーションのタイミングなどに関連していることはわかっていますが、html/js の初心者として、そのコンテキストでこれらの問題を十分に経験していないため、最適な解決策を知ることができません。

最初の行をクリックして、各クリックの間に数秒待つとうまくいきますが、猛烈にクリックするとすぐに問題が発生し始めます。

ありがとう

http://jsfiddle.net/mungbeans/wqUgC/

4

2 に答える 2

0

簡単な解決策は、追加のアニメーションが起動されないようにする単純なロックを追加することです。私はここでそうしました。

コードに関するいくつかのメモ - コードのアニメーション ロックは、おそらくコードの他の部分からはアクセスできないはずなので、別のコンテキストに入れました。また、すべてが適切なタイミングで起動するようにするために、アニメーション レートを処理する「アニメーション時間」という単一の整数コントロールを追加しました。

于 2012-09-06T22:27:44.043 に答える
0

これは、あなたが思っているよりも一般的な問題です。問題は、要素を に設定するイベントが設定されていることですdisplay: none。しかし、もう一度クリックすると、そのイベントが発生しないようにする必要があります。したがって、要素の非表示をキャンセルする必要がある場合にその参照setTimeout()を呼び出すことができるように、イベントへの参照を保持する必要があります (これを返します)。clearInterval()

var listener = (function() {
    var interval = 0; //A variable to retain the interval            

    return function() { //return the original function into listener
        var title = document.getElementById('title');

        //dismiss any plans to hide/show the element because we've changed our minds
        // (if the event already fired, this does nothing, which is fine):
        clearInterval(interval); 

        if (title.dataset.displayed == 'yes') {
            title.dataset.displayed = 'no';
            setTimeout(function () {
            title.style.webkitTransition = "opacity 2.0s ease";
            title.style.opacity = 0.0;
            }, 0);

            //don't forget to hold onto the interval!
            interval = setTimeout(function() { title.style.display = 'none'; }, 2000);
        }
        else {
            title.dataset.displayed = 'yes';
            title.style.display = 'block';

            //It's probably not necessary to retain the interval here. 
            // But it doesn't hurt anything.
            interval = setTimeout(function () {
                title.style.webkitTransition = "opacity 2.0s ease";
                title.style.opacity = 1.0;
            }, 0);
        }
    };
}());


var li = document.getElementById('list');
li.addEventListener("click", listener, false);

元の関数を返す、すぐに呼び出されるより大きな関数式内にリスナー関数をラップしたことに注意してください。intervalある呼び出しから次の呼び出しまで保持されるように、これを行いlistener()ました。グローバル変数を作成することもできintervalますが、それらはいたずらであり、このソリューションははるかに楽しく自己完結型です。

JSFiddle にスワップするとうまくいくようです。残りのコードもお疲れ様でした!

于 2012-09-06T22:28:11.547 に答える