2

fadeIn()Javascriptを使用して関数を作成しようとしています。ボタンをクリックしてもアニメーションfadeInが実行されず、fadeInフェードインするために何度かクリックする必要があります。この問題を解決する方法を知っている人はいますか?

jsフィドル

// Created a jQuery like reference
function $(selector) { 
    if (!(this instanceof $)) return new $(selector); // if new object is not defined, return new object
    this.selector = selector; // setting selector attribute
    this.node = document.querySelector(this.selector); // finds single element from the DOM
};

var fInFrom = 0, fOutFrom = 10;

$.prototype.fadeIn = function() {
    var target = this.node,
        newSetting = fInFrom / 10;

    // Set Default styles for opacity   
    target.style.display = 'block';
    target.style.opacity = newSetting;

    // fadeInFrom will increment by 1
    fInFrom++;

    var loopTimer = setTimeout('this.fadeIn', 50);

    if (fInFrom === 10) {
        target.style.opacity = 1;
        clearTimeout(loopTimer);
        fInFrom = 0;
        return false;
    }

    return this;
}

$('#fadeIn').node.addEventListener('click', function() {
    $('#box').fadeIn();
});
4

1 に答える 1

4

この行はあなたの問題です:

setTimeout('this.fadeIn', 50)

this.fadeInこれにより、現在の時刻から約 50 ミリ秒でグローバル スコープで式を評価するためのタイムアウトが設定されます。これには 2 つの問題があります。

  1. これはグローバル スコープにあります。thiswindow、のインスタンスではなく$、そうthis.fadeInですundefined
  2. 正しく解決されたとしても、評価しているだけですthis.fadeIn。あなたはそれを呼んでいません。this.fadeIn()何かをするためにそれを使用する必要があります。(現在のコードでこれを行うと、最初の問題が明らかになります。)

これを解決するには、文字列ではなく、必要な機能を実行する関数を渡します。あなたは単純にこれを行うかもしれません:

setTimeout(function() {
    this.fadeIn();
}, 50);

残念ながら、現在では変数のレキシカル スコープがありますがthis、JavaScript では動的です。私たちはそれを回避する必要があります。変数のレキシカルスコープがあるので、それを利用できます: [試してみる]

var me = this;  // store the current value of this in a variable
var loopTimer = setTimeout(function() {
    me.fadeIn();
}, 50);

それが解決したら、次のことを調べてください。

  1. フェード状態を保持するためにグローバル変数を使用しない。その修正の後でも、異なる要素で 2 つのフェード アニメーションを同時に実行すると、期待どおりに動作しません。(やってみてください。 )
  2. 必要な場合にのみタイムアウトを設定します。現時点では、常に設定してから、必要がなければクリアします。最初に必要な場合にのみ設定することをお勧めします。
于 2013-08-04T03:37:08.067 に答える