好的,我不使用 jquery,而且很可能我不知道你想要实现什么。但是据我了解,我认为您应该这样做:
var i = 0;
var t = this;
var timer = new DeltaTimer(function (time) {
// your animation
var x = t.s[i];
x.delay("1000").css("background-color", "#FAAF16");
delete t.s[i];
t.s.push(x);
// increment i
i++;
}, 1000);
var start = timer.start();
您会注意到这里我使用了一个名为DeltaTimer
. 此构造函数在此gist中定义。它允许您使用start
和stop
功能精确控制动画。传递的render
函数有一个time
参数,它是 a Date
。该表达式time - start
给出了调用函数的确切时间(例如4
, 1000
, 2000
, ...)。
使用DeltaTimer
over setTimeout
or的好处setInterval
是:
- 它会自行纠正。这意味着动画更流畅,延迟更少。
- 可以通过启动和停止计时器来控制动画。
- 函数调用的确切时间被传递给函数。这有助于跟踪正在渲染的帧,应该在哪里渲染精灵等。
- 动画的逻辑与时序控制的逻辑是分开的。因此,代码更具凝聚力和更松散的耦合。
您可以在此处、此处和此处阅读我关于增量计时的其他答案。
编辑1:这实际上很简单。我们只需移出数组的第一个元素,对其进行处理,然后在最后将其推回。这是逻辑:
function loopIterate(array, callback, interval) {
var timer = new DeltaTimer(function (time) {
var element = array.shift();
callback(element, time - start);
array.push(element);
}, interval);
var start = timer.start();
};
现在我们可以创建一个数组并循环遍历它,如下所示:
var body = document.body;
loopIterate([1, 2, 3], function (element, time) {
body.innerHTML += element + ": " + time + "<br/>";
}, 1000);
你可以在这里看到输出:http: //jsfiddle.net/aGQfr/
编辑2:糟糕,我发现了一个问题。据我了解,您希望在当前元素完成处理后的一段时间内处理下一个元素。我的增量计时脚本没有这样做。它仅以固定的时间间隔执行功能。
所以,你根本不需要增量时间。您需要在setTimeout
处理完每个元素后调用:
function loopIterate(array, callback, interval) {
var start = + new Date;
process();
function process() {
var element = array.shift();
callback(element, new Date - start);
array.push(element);
setTimeout(process, interval);
}
};
之后只需创建一个数组并循环遍历它,如下所示:
loopIterate([1, 2, 3], function (element, time) {
alert(element);
}, 1000);
你可以在这里看到演示(注意你的浏览器可能不喜欢它):http: //jsfiddle.net/aGQfr/1/
编辑3:您还可以组合方法一和方法二,以便您拥有一个脚本:
- 在将下一个要处理的元素添加到事件队列之前等待处理完成。
- 可以使用
start
和stop
功能进行控制。
- 给出调用回调的确切时间。
- 将处理与时序控制分开。
我们将创建一个名为的构造函数LoopIterator
,它返回一个带有start
和stop
方法的迭代器对象:
function LoopIterator(array, callback, interval) {
var start, iterate, timeout;
this.start = function () {
if (!iterate) {
start = + new Date;
iterate = true;
loop();
}
};
this.stop = function () {
if (iterate) {
clearTimeout(timeout);
iterate = false;
}
};
function loop() {
var element = array.shift();
callback(element, new Date - start);
array.push(element);
if (iterate) timeout = setTimeout(loop, interval);
}
}
现在我们可以创建并启动一个新的迭代器,如下所示:
var iterator = new LoopIterator([1, 2, 3], function (element, time) {
alert(element);
}, 3000);
iterator.start();
如果您希望您甚至可以分别在鼠标移到元素上或移出元素时停止和启动迭代器:
var div = document.getElementsByTagName("div")[0];
div.addEventListener("mouseout", iterator.start, false);
div.addEventListener("mouseover", iterator.stop, false);
当停止时,迭代器的状态被保留,当再次启动时,它从停止的地方继续。
您可以在这里看到演示:http: //jsfiddle.net/PEcUG/
编辑 4:所以你想创建一个简单的滑块?让我们从 HTML 开始,然后是 CSS,然后是 JavaScript。
的HTML:
<div class="slider">
<div class="slide">Slide 1</div>
<div class="slide">Slide 2</div>
<div class="slide">Slide 3</div>
</div>
我们有一个div
元素,其类名为slider
(因为页面上可能有多个滑块)。每个滑块都有零个或多个div
带有 class 的元素slide
。每张幻灯片可能有任意内容。滑块也会有按钮,但我们不将其包含在 HTML 中,因为它将由 JavaScript 自动生成。没有冗余。另请注意,没有一张幻灯片是手动编号的。一切都由 JavaScript 处理。
CSS:
.slide {
background-color: #EEEEEE;
-moz-border-radius: 0.25em;
-webkit-border-radius: 0.25em;
border-radius: 0.25em;
display: none;
padding: 1em;
}
.slider-button {
background-color: #CCCCCC;
-moz-border-radius: 0.25em;
-webkit-border-radius: 0.25em;
border-radius: 0.25em;
cursor: pointer;
float: right;
height: 1.25em;
margin: 0.5em;
width: 1.25em;
}
您可以提供任意 CSS 以满足您的口味。然而,重要的一点是.slide
必须有display: none;
,因为幻灯片最初必须是隐藏的。也.slider-button
必有float: right;
。这很重要,因为向右浮动的元素的顺序颠倒了。因此,第一个按钮实际上是最后一个按钮。这必须由 JavaScript 正确处理,因此除非您知道自己在做什么,否则不要更改它。
JavaScript:
好吧,我将自下而上解释:
window.addEventListener("DOMContentLoaded", function () {
var sliders = document.querySelectorAll(".slider");
var length = sliders.length;
for (var i = 0; i < length; i++)
new Slider(sliders[i], 2000);
}, false);
这Slider
是一个构造函数,它初始化并启动它传递的滑块元素。它接受两张幻灯片之间的时间间隔作为第二个参数。这是代码Slider
:
function Slider(slider, interval) {
var slides = slider.querySelectorAll(".slide");
var iterate, start, timeout, delay = interval;
slides = Array.prototype.slice.call(slides);
var buttons = [], numbers = [], goto = [];
var length = slides.length;
for (var i = 0; i < length; i++) {
var button = document.createElement("div");
button.setAttribute("class", "slider-button");
slider.appendChild(button);
buttons.unshift(button);
numbers.push(i + 1);
var handler = getHandler(length - i);
button.addEventListener("click", handler, false);
goto.unshift(handler);
}
this.goto = function (index) {
var gotoSlide = goto[index];
if (typeof gotoSlide === "function")
gotoSlide();
};
slider.addEventListener("mouseover", stop, false);
slider.addEventListener("mouseout", start, false);
this.start = start;
this.stop = stop;
showSlide();
start();
function start() {
if (!iterate) {
iterate = true;
start = + new Date;
timeout = setTimeout(loop, delay);
}
}
function stop() {
if (iterate) {
iterate = false;
clearTimeout(timeout);
delay = interval - new Date + start;
}
}
function loop() {
hideSlide();
slideSlider();
showSlide();
if (iterate) {
start = + new Date;
timeout = setTimeout(loop, interval);
}
}
function hideSlide() {
slides[0].style.display = "none";
buttons[0].style.backgroundColor = "#CCCCCC";
}
function slideSlider() {
slides.push(slides.shift());
buttons.push(buttons.shift());
numbers.push(numbers.shift());
}
function showSlide() {
slides[0].style.display = "block";
buttons[0].style.backgroundColor = "#FAAF16";
}
function getHandler(number) {
return function () {
hideSlide();
while (numbers[0] !== number) slideSlider();
showSlide();
};
}
}
该代码非常不言自明。的每个实例Slider
都有一个start
,stop
和goto
用于更好控制的方法。该goto
方法采用幻灯片索引号。对于n
幻灯片,索引范围从0
到n - 1
。而已。
滑块的演示在这里:http: //jsfiddle.net/SyTFZ/4/