2016-07-01 16 views
0

Ich mache eine Chrome-Erweiterung, die bestimmten Text auf einer Seite durch neuen Text und einen Link ersetzt. Dazu benutze ich document.body.innerHTML, was ich gelesen habe bricht das DOM. Wenn die Erweiterung aktiviert ist, scheint das Laden von YouTube Videos und Seiten bei codepen.io zu brechen. Ich habe versucht, dies zu beheben, indem ich YouTube und codepen im Manifest ausklammere und sie im folgenden Code ausfiltere, aber es scheint nicht zu funktionieren.Chrome Erweiterung bricht DOM

Kann jemand vorschlagen, eine Alternative zur Verwendung von document.body.innerHTML oder sehen Sie andere Probleme in meinem Code, die Seitenlasten zu brechen? Vielen Dank.

var texts=["some text","more text"]; 
if(!window.location.href.includes("www.google.com")||!window.location.href.includes("youtube.com")||!window.location.href.includes("codepen.io")){ 
for(var i=0;i<texts.length;i++){ 
    if(document.documentElement.textContent || document.documentElement.innerText.includes(texts[i])){ 

     var regex = new RegExp(texts[i],'g'); 

     document.body.innerHTML = document.body.innerHTML.replace(regex, 
"<a href='https://www.somesite.org'>replacement text</a>"); 
     } 
    } 
} 
+0

Erstens, jede Seite aufzulisten, die es nicht funktioniert, skaliert nicht schrecklich gut auf das gesamte Internet. –

+0

Ja, ich bin mir bewusst. Deshalb bitte ich um Hilfe. Aber es scheint, dass diese Seiten aus dem Manifest ausgeschlossen werden. ** sollte nur für diejenigen funktionieren, die mir bekannt sind, und das ist es nicht. – mostlynew

Antwort

1

innerHTML Mit diesem zu tun ist wie eine Schrotflinte mit Gehirnchirurgie zu tun. Ganz zu schweigen davon, dass dies sogar zu ungültigem HTML führen kann. Am Ende müssen Sie jede einzelne Website, die JavaScript verwendet, auf die weiße Liste setzen, was natürlich nicht möglich ist.

Der korrekte Weg ist, innerHTML überhaupt nicht zu berühren. Wiederholen Sie rekursiv alle DOM-Knoten (mit firstChild, nextSibling) auf der Seite und suchen Sie nach Übereinstimmungen in Textknoten. Wenn Sie einen gefunden haben, ersetzen Sie diesen einzelnen Knoten (replaceChild) durch Ihren Link (createElement) und neue Textknoten (createTextNode, , insertBefore) für alle übrig gebliebenen Bits.

Im Wesentlichen werden Sie für einen Knoten zu wie folgt aussehen:

Text: this is some text that should be linked 

Und programmatisch ersetzen Sie es mit Knoten wie:

Text: this is 
Element: a href="..." 
    Text: replacement text 
Text: that should be linked 

Zusätzlich, wenn Sie Websites unterstützen möchten, die Inhalte mit JavaScript generieren Sie Dieser Ersetzungsprozess muss auch auf dynamisch eingefügten Inhalten ausgeführt werden. A MutationObserver wäre eine Möglichkeit, dies zu tun, aber bedenken Sie, dies wird wahrscheinlich Websites verlangsamen.

+0

Wie würde ich einen HTML-Link in Textknoten einfügen? – mostlynew

+0

@mostlynew: Sie können kein Element in einen Textknoten einfügen, aber Sie können ein Element daneben einfügen oder durch ein Element ersetzen. Dies alles geschieht mit dem DOM, ich gebe Funktionsnamen als Zeiger ein. –

+0

Aha. Vielen Dank! – mostlynew