喵喵时光机
您可以将主计时器包含在一个间隔内,并将每个突出显示事件作为单独的超时。我还会向您要查询的元素添加一个类,或者只选择所有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>