2017-10-20 52 views
0

我試着用以下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

回答

2
  • 枚舉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