2

我正在尝试fadeIn()使用 Javascript 创建函数。我遇到了麻烦,当我单击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();
});
4

1 回答 1

4

这条线是你的问题:

setTimeout('this.fadeIn', 50)

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

  1. 它在全球范围内;thisis window,不是 的实例$,所以this.fadeInis 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. 仅在需要时设置超时;现在,您总是设置它,然后在不需要时将其清除。如果您首先需要它,您可能只想设置它。
于 2013-08-04T03:37:08.067 回答