繁体   English   中英

JS Class 发出信号以创建事件链

[英]JS Class Emit Signal to create chain of events

我为我为移动设备设计的 vue 项目编写了一个更大的 js class。 但是,我需要我的 class 发出信号,这样我就可以根据 class 的完成情况将其他事件链接在一起。 当我的 class object 的属性“hasEnded”设置为 True 时,如何发出信号?

在这种情况下,当用户在第一个计时器计数到 100 时立即单击“开始”,它应该触发下一个计时器开始。 我希望 class 可重复使用,我想让它触发事件或信号是最好的。

我对移动开发没有丰富的知识,所以如果手机不支持事件,那么这里有什么替代方案?

 class Counter { constructor(name) { this.hasEnded = false; this.value = 0; this.maxValue = 100; this.intervalID = null; this.elementName = '' this.elementName = name; } start() { this.intervalID = setInterval(this.increment.bind(this), 10); } increment() { this.value++ var el = document.querySelector('.' + this.elementName); el.innerHTML = this.value; if (this.value == this.maxValue) { this.hasEnded = true clearInterval(this.intervalID); } } } window.addEventListener('load', function() { let counterA = new Counter('counterA'); let counterB = new Counter('counterB'); /* -- psuedo code -- when counterA.hasFinished == true { counterB.start() } */ var start = document.querySelector('.start'); start.addEventListener('click', function() { counterA.start(); }); })
 <button class="start">Start</button> <br> <label>CounterA:</label> <label class="counterA"></label> <br> <label>CounterB</label> <label class="counterB"></label>

作为信号发出的最简单方法是使用EventTarget.dispatchEvent()调度事件。 windowdocument和每个 HTML 元素是此 class 的扩展,因此每个上述 ZA8CFDE6331BD59EB66AC96F8911ZB 方法都有此方法。 这使您可以发送其他实例可以收听的信号。

要按顺序运行您的计数器,您需要一个以列表形式运行的系统。 该列表从索引0的开头开始,一直持续到该列表中没有其他项目为止。

结合事件的调度和列表的结构来让它工作。 每次触发特定事件时,移动到列表中的下一项。

下面的示例使用了这些技术。 我创建了一个新的 class CounterCollection来控制列表。 它侦听一个名为counterend的自定义事件,每次计数器(您猜对了)到达末尾时都会触发该事件。 然后它将 go 到列表中的下一个计数器并运行该计数器,直到列表用完。 为了演示,我添加了一个reset function 以便您可以多次运行它。

 class CounterCollection { constructor(...counters) { this.counterIndex = 0; this.amountOfCounters = counters.length; this.counters = counters; window.addEventListener('counterend', this.nextCounter.bind(this)); } // Start the counter with the current index. start() { const counter = this.counters[this.counterIndex]; counter.start(); } // Go to the next timer and start it if possible. // Otherwise, reset. nextCounter() { if (this.counterIndex + 1 < this.amountOfCounters) { this.counterIndex++; this.start(); } else { this.counterIndex = 0; this.counters.forEach(counter => { counter.reset(); }); } } } class Counter { constructor(name) { this.hasEnded = false; this.value = 0; this.maxValue = 100; this.intervalID = null; // It's less expensive to store the element here. this.element = document.querySelector('.' + name); } start() { this.intervalID = setInterval(this.increment.bind(this), 10); } increment() { this.value++ this.element.textContent = this.value; if (this.value == this.maxValue) { this.hasEnded = true clearInterval(this.intervalID); // The counter is finished, fire the event. const counterEndEvent = new Event('counterend'); window.dispatchEvent(counterEndEvent); } } // I've added this for the demonstration, so you can run it multiple times. reset() { this.value = 0; this.element.textContent = this.value; } } window.addEventListener('load', function() { let counterA = new Counter('counterA'); let counterB = new Counter('counterB'); // Pass the counters into the collection. const counters = new CounterCollection(counterA, counterB); var start = document.querySelector('.start'); start.addEventListener('click', function() { // Start the collection. counters.start(); }); });
 <button class="start">Start</button> <br> <label>CounterA:</label> <label class="counterA"></label> <br> <label>CounterB</label> <label class="counterB"></label>

事件是部分 JavaScript 和 web。 如果您想知道您正在使用的浏览器是否支持技术、API 或语法,请查看caniuse.com以了解您可以使用什么。

暂无
暂无

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

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