首页 > 解决方案 > 在 Web 浏览器或 Node 内部,为什么如果你不监听它就不会发生事件,但是一旦你监听它,它就会发生?

问题描述

我看到的事件是voiceschanged。您可以加载about:blank或任何不做语音的网页,然后等待10分钟,然后再做一个window.speechSynthesis.getVoices(),它仍然是一个空数组。所以voiceschanged那10分钟从来没有发生过。

但是再次刷新您的页面,并打开相同的网页或about:blank再次打开,一旦您收听voiceschanged,事件将发生:

window.speechSynthesis.addEventListener('voiceschanged', function(ev) {
  console.log(window.speechSynthesis.getVoices())
});

你如何理解这种行为?(在浏览器或节点中)。这是我以前从未见过的奇怪行为。

我在 Mac 上使用 Chrome v79 和 Edge 79 尝试上述代码。如果在 Firefox v72 上尝试了相同的代码,则不会触发该事件。您可以设置侦听器,然后执行 a window.speechSynthesis.getVoices(),它将返回一个空数组,但随后该事件将触发,因此您必须调用window.speechSynthesis.getVoices()两次才能获得声音。但是 Firefox 会缓存结果,因此即使您刷新页面并执行 a window.speechSynthesis.getVoices()then 它也会立即返回一组声音。

因此,结合 Chrome 和 Firefox 上的行为,如果你必须让它工作,那么你必须这样做:

let voices = window.speechSynthesis.getVoices();

if (voices.length === 0) { 
  window.speechSynthesis.addEventListener('voiceschanged', function(ev) {
    voices = window.speechSynthesis.getVoices();
  });
}

那是window.speechSynthesis.getVoices()需要调用两次。您如何理解这种行为?通常,我们会考虑调用该函数一次,但不会考虑调用两次来获取某些东西。

标签: javascriptdom-events

解决方案


推荐阅读