音频不会使用JavaScript静音 - 消除音频标签与mutationobserver需要

问题描述:

我试着用以下userscript从某个网站上删除所有音频:音频不会使用JavaScript静音 - 消除音频标签与mutationobserver需要

// ==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正是我需要更好地处理这个问题。

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

+0

可能不是一个问题,但请注意,你的脚本将不静音,可以由制表扩散的声音,只有那些在DOM作为HTMLAudioElement内附加的那些所有可能的来源。如果位于iframe中,它将会丢失所有不在DOM中的HTMLAudioElements,所有视频元素,所有AudioContexts以及所有上述+附加到DOM。如果真正的扩展是一个选项,那么使用[chrome.tabs API](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/update)可能更容易'update(tabId,{muted:true})'方法 – Kaiido

  • 枚举mutations每个突变的addedNodes
  • 枚举节点的子元素,因为突变页面加载过程中使用超快的getElementsByTagName而不是superslow querySelectorAll
  • 不要使用@grant none合并,它运行在您的userscript页面上下文,除非您确实需要直接访问页面的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.children && node.children[0]) { 
      for (const child of node.getElementsByTagName('audio')) { 
      audio.muted = true; 
      } 
     } 
     } 
    } 
    }).observe(document, {subtree: true, childList: true}); 
} 
+0

对我来说非常有意思,我会在实现之前至少读取2到3次。我有2个问题,请。为什么'(node.children && node.children [0])'?我的意思是,如果在第一部分('node.children')中,所有的孩子都去了,为什么你在之后标记第一个(0)? – fayalikt

+0

另外,关于'// @ run-at document-start'是否必须?我从来没有用过我写的20个脚本中的任何一个。我知道这是默认行为,但也许我错了。 – fayalikt

+0

1.文本节点没有'children',所以第一次检查会跳过它们,'children [0]'意味着“至少有一个元素子节点”。2. document-start表示脚本处理页面,因为它仍然存在加载。 – wOxxOm