jtml元素方法运行setTimeout后返回此javascript

时间:2015-03-22 00:27:47

标签: javascript prototype method-chaining htmlelements

好的,所以我有这个代码,添加一个方法(从我的理解)到HTML元素原型:

HTMLElement.prototype.fadeIn = function( seconds ) {

var self = this;
var miliseconds = seconds * 1000;
var hold = this.style.transition;
this.style.transition = "opacity " + seconds + "s ease";
this.style.opacity = 1;

setTimeout(
    function () {
        self.style.transition = hold;
        return self;
    },
miliseconds);

};

我的意图是,在超时结束时,函数将返回HTMLElement的实例,这样我就可以将fadeIn函数与另一个函数链接起来。

然而事实并非如此,并且将一个console.log作为它返回的内容,它说它未定义。任何人都可以就如何做到这一点提出一些建议?

2 个答案:

答案 0 :(得分:0)

setTimeout()是一个异步操作。它没有"暂停"执行fadeIn()功能。您的.fadeIn()方法立即返回,然后定时器操作发生。

self回调中返回setTimeout()没有任何用处。它只是将self返回到计时器子系统的内部区域,在那里它被尽职尽责地忽略。

您只需在方法的末尾添加.fadeIn()即可支持return this;操作中的链接:

HTMLElement.prototype.fadeIn = function( seconds ) {
    var self = this;
    var miliseconds = seconds * 1000;
    var hold = this.style.transition;
    this.style.transition = "opacity " + seconds + "s ease";
    this.style.opacity = 1;

    setTimeout(
        function () {
            self.style.transition = hold;
        }, miliseconds);
    return this;
};

但是,这并不能告诉你关于淡入淡出操作何时实际完成的任何信息。如果你想知道这一点,你将不得不在你的方法(回调或承诺或队列)中设计其他东西,以支持动画链接。


如果您尝试像jQuery那样进行动画链接,那么您可以这样做:

obj.fadeIn(5).fadeOut(5);

并且两个动画将按顺序发生,然后将需要更复杂的系统。 jQuery使用动画队列,其中动画不一定立即执行,而是将其添加到特定于该特定DOM对象的队列中。每当该特定对象的动画完成时,它就会查看其队列以查看是否有另一个动画等待同一个对象。如果是这样,它会启动该动画。

此外,如果您正在使用CSS3动画并且您需要知道动画何时完成,则需要在对象上注册transitionend事件。

答案 1 :(得分:0)

你不能在超时后返回一些东西,因为赫拉克利特流已经移动了:你还要回到哪里?

链接具有延迟的函数的一种简单方法是将它们传递给:

HTMLElement.prototype.fadeIn = function(seconds, continueWith) {
var self = this;
var miliseconds = seconds * 1000;
var hold = this.style.transition;
this.style.transition = "opacity " + seconds + "s ease";
this.style.opacity = 1;
setTimeout(
    function () {
        self.style.transition = hold;
        if(continueWith)
          continueWith();
    },
miliseconds);
};

你可以用el.fadeIn(1.5, function(){el.fadeOut(2);})来调用它;然后在fadeOut完成后调用fadeIn

您还可以返回一个promise对象:

function createTimeoutPromise(timeOut)
{
    var promise = 
    {
        toRun: null,
        continueWith: function(func)
        {
            this.toRun = func;
        }
    }
    setTimeout(function()
    {
        if(promise.toRun)
            promise.toRun();
    }, timeOut);
    return promise;
}

HTMLElement.prototype.fadeIn = function(seconds)
{
    var self = this;
    var miliseconds = seconds * 1000;
    var hold = this.style.transition;
    this.style.transition = "opacity " + seconds + "s ease";
    this.style.opacity = 1;
    return createTimeoutPromise(miliseconds);
};

然后您可以调用此方法,您可以使用el.fadeIn(1.5).continueWith(function(){el.fadeOut(2);});调用此方法,这可能是一种更好的链接方式。

请注意,在这两种情况下,我们都会检查是否存在无法继续执行的功能,因此链的末尾不会导致错误。