简体   繁体   English

超时循环功能

[英]Looping functions with timeout

I want to have two functions (an animation downwards and animation upwards) executing one after the other in a loop having a timeout of a few seconds between both animations. 我想让两个函数(向下动画和向上动画)在一个循环中一个接一个地执行,两个动画之间都有几秒钟的超时。 But I don't know how to say it in JS … 但是我不知道如何在JS中说...

Here what I have so far: 这是我到目前为止所拥有的:

Function 1 功能1

// Play the Peek animation - downwards
function peekTile() {
    var peekAnimation = WinJS.UI.Animation.createPeekAnimation([tile1, tile2]);

    // Reposition tiles to their desired post-animation position
    tile1.style.top = "-150px";
    tile2.style.top = "-150px";

    peekAnimation.execute();
}

Function 2 功能2

// Play the Peek animation - upwards
function unpeekTile() {
    var peekAnimation = WinJS.UI.Animation.createPeekAnimation([tile1, tile2]);

    // Reposition tiles to their desired post-animation position
    tile1.style.top = "0px";
    tile2.style.top = "0px";

    peekAnimation.execute();
}

And here's a sketch how both functions should be executed: 这是两个函数应如何执行的示意图:

var page = WinJS.UI.Pages.define("/html/updateTile.html", {
    ready: function (element, options) {

    peekTile();
    [timeOut]
    unpeekTile();
    [timeOut]
    peekTile();
    [timeOut]
    unpeekTile();
    [timeOut]

    and so on …
    }
});

You can do this using setTimeout or setInterval , so a simple function to do what you want is: 您可以使用setTimeoutsetInterval来执行此操作,因此一个简单的函数即可完成:

function cycleWithDelay() {
    var delay = arguments[arguments.length - 1],
        functions = Array.prototype.slice.call(arguments, 0, arguments.length - 1),
        pos = 0;
    return setInterval(function () {
        functions[pos++]();
        pos = pos % functions.length;
    }, delay);
}

Usage would be like this for you: 用法对您来说是这样的:

var si = cycleWithDelay(peekTile, unpeekTile, 300);

and to stop it: 并停止它:

clearInterval(si);

This will just cycle through the functions calling the next one in the list every delay msec, repeating back at the beginning when the last one is called. 这只会在每个delay毫秒内循环调用列表中的下一个函数,并在调用最后一个函数时从头开始重复。 This will result in your peekTile , wait, unpeekTile , wait, peekTile , etc. 这将导致您的peekTile ,wait, unpeekTile ,wait, peekTile等。

If you prefer to start/stop at will, perhaps a more generic solution would suit you: 如果您愿意随意启动/停止,也许更通用的解决方案适合您:

function Cycler(f) {
    if (!(this instanceof Cycler)) {
        // Force new
        return new Cycler(arguments);
    }
    // Unbox args
    if (f instanceof Function) {
        this.fns = Array.prototype.slice.call(arguments);
    } else if (f && f.length) {
        this.fns = Array.prototype.slice.call(f);
    } else {
        throw new Error('Invalid arguments supplied to Cycler constructor.');
    }
    this.pos = 0;
}

Cycler.prototype.start = function (interval) {
    var that = this;
    interval = interval || 1000;
    this.intervalId = setInterval(function () {
        that.fns[that.pos++]();
        that.pos %= that.fns.length;
    }, interval);
}

Cycler.prototype.stop = function () {
    if (null !== this.intervalId) {
        clearInterval(this.intervalId);
        this.intervalId = null;
    }
}

Example usage: 用法示例:

var c = Cycler(peekTile, unpeekTile);
c.start();

// Future
c.stop();

You use setInterval() to call unpeekTile() every 1000 milliseconds and then you call setTimeOut() to run peekTile() after 1000 milliseconds at the end of the unpeekTile() function: 您使用setInterval()调用unpeekTile()每隔1000毫秒,然后调用setTimeOut()来运行peekTile()后,在结束1000毫秒unpeekTile()函数:

function peekTile() {
    var peekAnimation = WinJS.UI.Animation.createPeekAnimation([tile1, tile2]);

    // Reposition tiles to their desired post-animation position
    tile1.style.top = "-150px";
    tile2.style.top = "-150px";

    peekAnimation.execute();
}

function unpeekTile() {
       /* your code here */
     setTimeout(peekTile, 1000);
}

setInterval(unpeekTile, 1000);

Check out the fiddle 查看小提琴

var animation  = (function () {
     var peekInterval, unpeekInterval, delay;
     return {
          start: function (ip) {
              delay = ip;
              peekInterval = setTimeout(animation.peekTile, delay);
          },
          peekTile: function () {
             //Your Code goes here
             console.log('peek');
             unpeekInterval = setTimeout(animation.unpeekTile, delay);
          },
          unpeekTile: function () {
            //Your Code goes here
            console.log('unpeek');  
            peekInterval = setTimeout(animation.peekTile, delay);
          },
          stop: function () {
              clearTimeout(peekInterval);
              clearTimeout(unpeekInterval);
          }
    }
         })();
animation.start(1000);
// To stop

setTimeout(animation.stop, 3000);

​ I can't use this instead of animation.peekTile as setTimeout executes in global scope 我不能使用this代替animation.peekTile,因为setTimeout在全局范围内执行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM