【问题标题】:Audio won't be muted with JavaScript - removing audio tags with mutationobserver needed音频不会被 JavaScript 静音 - 需要使用 mutationobserver 删除音频标签
【发布时间】:2017-10-20 07:18:01
【问题描述】:

我尝试使用以下用户脚本从某个网站删除所有音频:

// ==UserScript==
// @name        addicto
// @namespace   nms
// @include     http://*
// @include     https://*
// @version     1
// @grant       none
// ==/UserScript==

addEventListener('DOMContentLoaded', ()=>{
  let sites = ['mako.co.il'];
  let href = window.location.href;
  for (let i = 0; i < sites.length; i++) {
    if (href.includes(sites[i])) {
      Array.prototype.slice.call(document.querySelectorAll('audio')).forEach((audio)=>{
        audio.muted = true;
      });
    }
  }

  // If href includes the value of the iteration on the "sites" array, do stuff.
});

这段代码不起作用,我认为观察所有随机出现的 audio 标签并改变 DOM 正是我需要更好地处理这个问题。

这个变异观察者怎么写?我从来没有写过一个变异观察者,我觉得这个例子会很短而且非常基本,正是我需要了解我刚刚描述的逻辑的代码上下文,我非常感谢任何愿意试着把它展示给我和其他遇到类似问题的人。

【问题讨论】:

  • 可能不是问题,但请注意,您的脚本不会静音所有可能由选项卡传播的声音来源,只会静音作为 HTMLAudioElement 附加到 DOM 中的声音来源。如果在 iframe 中,它将错过所有不在 DOM 中的 HTMLAudioElements、所有视频元素、所有 AudioContexts 以及所有上述 + 附加到 DOM 的内容。如果一个真正的扩展是一个选项,那么使用chrome.tabs APIupdate(tabId, {muted:true}) 方法可能会更容易

标签: javascript html5-audio mutation-observers


【解决方案1】:
  • 枚举mutations和每个突变的addedNodes
  • 枚举节点的子元素,因为在页面加载期间使用超快 getElementsByTagName 而不是超慢 querySelectorAll 合并突变
  • 不要使用@grant none,它会在页面上下文中运行您的用户脚本,除非您确实需要直接访问页面的 JavaScript 对象
  • 在页面加载期间使用@run-at document-start 将音频静音

// ==UserScript==
// @name     addicto
// @include  *
// @run-at   document-start
// ==/UserScript==

const sites = ['mako.co.il'];
if (sites.some(site => location.hostname.includes(site))) {
  new MutationObserver(mutations => {
    for (const m of mutations) {
      for (const node of m.addedNodes) {
        if (node.localName == 'audio') {
          audio.muted = true;
        } else if (node.firstElementChild) {
          for (const child of node.getElementsByTagName('audio')) {
            audio.muted = true;
          }
        }
      }
    }
  }).observe(document, {subtree: true, childList: true});
}

【讨论】:

  • 对我来说非常有趣,我会在实施之前至少再阅读 2 或 3 遍。请问我有2个问题。为什么是(node.children &amp;&amp; node.children[0])?我的意思是如果在第一部分 (node.children) 你继续所有的孩子,你为什么要在之后标记他们中的第一个 (0)?
  • 另外,关于// @run-at document-start 是必须的吗?我从未在我编写的 20 个脚本中使用过它。我知道这是默认行为,但也许我错了。
  • 1.文本节点没有children,因此第一次检查会跳过它们,children[0] 表示“至少一个元素子元素”2。document-start 表示脚本在页面仍在加载时对其进行处理。
  • 抱歉,文本节点?你的意思是textContent?我发誓我想念这里的意思。
  • textContent 是实际text nodes 的便捷访问器。
猜你喜欢
  • 1970-01-01
  • 2014-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多