4 回答
TA贡献1943条经验 获得超7个赞
感谢所有这些答案,但我自己找到了最简单、最干净的解决方案。只是前一个函数中的 settimeout 函数,以循环方式。它更加漂亮和清晰。下面是代码片段。
<body>
<h1 id="first">Text 1</h1>
<h1 id="second">Text 2</h1>
<h1 id="third">Text 3</h1>
</body>
<script>
first();
function first()
{
document.getElementById('third').style.color="#333";
document.getElementById('first').style.color="#32A067";
setTimeout(second,10000);
}
function second()
{
document.getElementById('first').style.color="#333";
document.getElementById('second').style.color="#32A067";
setTimeout(third,15000);
}
function third()
{
document.getElementById('second').style.color="#333";
document.getElementById('first').style.color="#32A067";
setTimeout(first,18000);
}
</script>
TA贡献1829条经验 获得超6个赞
您必须使用循环数组和超时来睡眠并调用该函数
listElements包含所有要突出显示的元素及其突出显示时间
startAutoIndex每次调用该函数时都会递增,因此它将首先从元素 id 开始
var startAutoIndex = 0
function startAuto() {
let listElements = [
{id: "first", timer: 10000},
{id: "second", timer: 13000},
{id: "third", timer: 26000}
]
function colorHeader(currentIndex) {
for (let index = 0; index < listElements.length; index++) {
const element = listElements[index]
if (currentIndex != index)
document.getElementById(element.id).style.color = '#333'
else {
document.getElementById(element.id).style.color = '#32A067'
}
}
}
let currentIndex =
((startAutoIndex % listElements.length) + listElements.length) %
listElements.length
colorHeader(currentIndex)
setTimeout(startAuto, listElements[currentIndex].timer)
startAutoIndex = currentIndex + 1
}
TA贡献1846条经验 获得超7个赞
您可以将主计时器包含在一个间隔内,并将每个突出显示事件作为单独的超时。
我还会向您要查询的元素添加一个类,或者只选择所有h1元素。
您还可以提供固定超时,它会为您计算元素之间的超时。
window.startAuto = () => {
start({
selector : '.highlighter',
timeouts : [ 1000, 2000, 1000 ], // or, for a fixed timout: 1000
callback : (el, index, activeIndex) => {
el.classList.toggle('active', index === activeIndex);
}
});
};
const defaultOptions = {
selector : '',
timeouts : [],
initialDelay : 0
};
const start = (options) => {
let opts = Object.assign({}, defaultOptions, options);
opts.elements = Array.from(document.querySelectorAll(opts.selector));
let interval = 0;
if (!Array.isArray(opts.timeouts)) {
opts.timeouts = fillArray(opts.timeouts, opts.elements.length);
}
interval = opts.timeouts.reduce((t, x) => t + x, 0);
opts.timeouts = normalizeTimeouts(opts.timeouts);
setTimeout(() => {
update(opts);
setInterval(update, interval, opts);
}, opts.initialDelay);
};
const normalizeTimeouts = (timeouts) => {
return timeouts.reduce((results, timeout, index, all) => {
return results.concat(timeout + all.slice(0, index).reduce((t, x) => t + x, 0));
}, [0]);
};
const update = (opts) => {
opts.timeouts.slice(0, opts.timeouts.length -1).forEach((timeout, index) => {
setTimeout(() => {
opts.elements.forEach((element, i) => {
return opts.callback.call(element, element, i, index);
});
}, timeout);
})
};
const fillArray = (value, count) => new Array(count).fill(value);
.active {
color: green;
}
<body onload="startAuto()">
<h1 class="highlighter" id="first">Text 1</h1>
<h1 class="highlighter" id="second">Text 2</h1>
<h1 class="highlighter" id="third">Text 3</h1>
</body>
这里有超动态;可重用的类。
document.addEventListener('DOMContentLoaded', () => main());
const main = () => {
let looper = new Looper({
selector : '.highlighter',
timeouts : [ 1000, 2000, 1000 ], // or, for a fixed timout: 1000
callback : (el, index, activeIndex) => {
el.classList.toggle('active', index === activeIndex);
},
initialDelay : 1000,
autoStart : true
})
document.querySelector('#stop-btn').addEventListener('click', (e) => {
looper.stop();
});
document.querySelector('#restart-btn').addEventListener('click', (e) => {
looper.stop();
looper.start();
});
}
class Looper {
constructor(options) {
let opts = Object.assign({}, Looper.defaultOptions, options);
this.elements = Array.from(document.querySelectorAll(opts.selector));
if (!Array.isArray(opts.timeouts)) {
opts.timeouts = this.__fillArray(opts.timeouts, this.elements.length);
}
this.interval = opts.timeouts.reduce((t, x) => t + x, 0);
this.timeouts = this.__normalizeTimeouts(opts.timeouts);
this.initialDelay = opts.initialDelay;
this.autoStart = opts.autoStart;
this.callback = opts.callback;
this.__startupId = null;
this.__processId = null;
this.__subprocessIds = this.__fillArray(null, this.elements.length);
if (this.autoStart === true) this.start();
}
start() {
if (this.callback == null) {
throw new Error('callback function is undefined');
}
if (this.__processId == null) {
this.__startupId = setTimeout(() => {
this.__update();
this.__processId = setInterval(() => {
this.__update();
}, this.interval);
}, this.initialDelay);
}
}
stop() {
this.__subprocessIds.forEach((id, index) => {
if (id != null) {
clearTimeout(id);
this.__subprocessIds[index] = null;
}
});
if (this.__processId != null) {
clearInterval(this.__processId);
this.__processId = null;
}
if (this.__startupId != null) {
clearTimeout(this.__startupId);
this.__startupId = null;
}
}
__update() {
let self = this;
self.timeouts.slice(0, this.timeouts.length -1).forEach((timeout, index) => {
self.__subprocessIds[index] = setTimeout(() => {
self.elements.forEach((element, i) => {
return self.callback.call(element, element, i, index);
});
}, timeout);
})
}
__normalizeTimeouts(timeouts) {
return timeouts.reduce((results, timeout, index, all) => {
return results.concat(timeout + all.slice(0, index).reduce((t, x) => t + x, 0));
}, [0]);
}
__fillArray(value, count) {
return new Array(count).fill(value);
}
}
Looper.defaultOptions = {
selector : '',
timeouts : [],
initialDelay : 0,
autoStart : false
}
.active {
color: green;
}
<div>
<h2 class="highlighter" id="first">Text 1</h2>
<h2 class="highlighter" id="second">Text 2</h2>
<h2 class="highlighter" id="third">Text 3</h2>
</div>
<button id="stop-btn">Stop</button>
<button id="restart-btn">Restart</button>
TA贡献1839条经验 获得超15个赞
您可以将 setTimeout 与 Promise 一起使用来实现您想要的结果。看看我的片段:
var first = document.getElementById('first');
var second = document.getElementById('second');
var third = document.getElementById('third');
const promiseTimeout = (delay, element, newColor) =>
{
return new Promise((resolve, reject) => {
setTimeout(() => {
element.style.color = newColor;
resolve() // when this fires, .then gets called
}, delay)
});
}
function start(){
first.style.color = "green";
promiseTimeout(10000, first, "#333")
.then(() => {
return second.style.color = "green";
})
.then(() => {
return promiseTimeout(15000, second, "#333")
})
.then(() => {
third.style.color = "green";
return promiseTimeout(18000, third, "#333")
})
.then(() => start());
}
start();
<h1 id="first">Text 1</h1>
<h1 id="second">Text 2</h1>
<h1 id="third">Text 3</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
- 4 回答
- 0 关注
- 121 浏览
添加回答
举报