自创的fadeIn()函数无法正常工作

时间:2013-08-04 03:28:58

标签: javascript

我正在尝试使用Javascript创建fadeIn()函数。我遇到了麻烦,当我点击fadeIn按钮时,它没有执行fadeIn动画,而是我必须多次点击才能淡入淡出。有谁知道如何解决这个问题?

jsFiddle

// 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();
});

1 个答案:

答案 0 :(得分:4)

这一行是你的问题:

setTimeout('this.fadeIn', 50)

这将设置一个超时,以便在距离当前时间大约50毫秒的时间内评估全局范围中的表达式this.fadeIn。这有两个问题:

  1. 它在全球范围内; thiswindow,而不是$的实例,因此this.fadeInundefined
  2. 即使它被正确解析,您也只是评估this.fadeIn;你没有打电话给它。您需要使用this.fadeIn()来执行任何操作。 (如果你使用当前代码执行此操作,这将显示您的第一个问题。)
  3. 要解决这个问题,不要传递一个字符串,而是传递一个你希望它做的事情的函数。你可能天真地这样做:

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

    不幸的是,虽然我们现在有变量的词法范围,但JavaScript中的this是动态的;我们必须解决这个问题。由于我们确实有变量的词法范围,我们可以利用: [ try it ]

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

    在解决之后,您可能需要查看:

    1. 不使用全局变量来保持淡入淡出状态。即使在修复之后,在不同元素上一次运行两个淡入淡出动画也无法按预期工作。 (Try it.
    2. 如果需要,只设置超时;现在,你总是设置它,然后如果你不需要它清除它。您可能只想在首先需要时设置它。