2016-08-01 4 views
0

Ich muss jeden #text, der Geschwister hat, durch Spannen ersetzen, so dass sie IDs haben. Der folgende Code soll dies tun, aber aus irgendeinem Grund verursacht es viele Dokumente neu zu gestalten: Teile des Dokuments verschieben, Seite ändert sich das Aussehen.Das Ersetzen von #text-Elementen durch Spannen führt dazu, dass Dokumente neu gestaltet werden.

var eltId = 0; 

function genEltId() { 
    return "my-id-" + ++eltId; 
} 

function hashTextsToSpans(elt) { 
    for (var i in elt.childNodes) { 
     var eltChild = elt.childNodes[i]; 
     if (eltChild.nodeName == "#text" && elt.childNodes.length > 1) { 
      // #text is one of multiple childs 
      var eltDiv = document.createElement("span"); 
      eltDiv.setAttribute("id", genEltId()); 
      elt.replaceChild(eltDiv, eltChild); 
      eltDiv.appendChild(eltChild); 
     } else { 
      if (eltChild.nodeName != "IFRAME") { 
       hashTextsToSpans(eltChild); 
      } 
     } 
    } 
} 

function onKeyPress(e) { 
    if (e.keyCode == 105) { 
     // key I 
     hashTextsToSpans(document.body); 
    } 
} 

window.parent.addEventListener("keypress", onKeyPress); 

Zum Beispiel injizieren sie in Chrom in https://en.wikipedia.org/wiki/Linux, drücken Sie "i" ("CJS" Add-on verwendet wird), und beobachten, dass die Seite neu formt.

Was ist das Problem? Sind nicht #text und span beide Inline-Elemente und sollten auf die gleiche Weise angezeigt werden, wenn der Text identisch ist und span keinen Stil hat?

Annahmen: keine Iframe-Elemente, kein anderes Javascript, das den DOM-Baum gleichzeitig manipuliert.

+0

Verwenden Sie ein beliebiges CSS Framework? – doge1ord

+0

keine Frameworks, ich injiziere js in Wikipedia als Beispiel mit "cjs" Addon. –

+0

Keine Antwort, aber vielleicht möchten Sie sich die [TreeWalker' API] (https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker) ansehen, die in allen modernen Browsern verfügbar ist und macht diese Aufgabe viel einfacher zu codieren und zu pflegen. – rvighne

Antwort

1

Das Problem besteht darin, dass viele Elemente in HTML Einschränkungen enthalten, welche Arten von untergeordneten Knoten sie enthalten dürfen.

Zum Beispiel können Listenelemente (z. B. ul oder ol) nur li Elemente und leere (nur Leerzeichen) Textknoten enthalten. Wenn Sie solche leeren Textknoten in Spannen umbrechen, ist die Seite plötzlich nicht standardkonform.

Im speziellen Fall der Wikipedia-Seite Textknoten verbunden, hatte die ursprüngliche Seite nur Leerzeichen zwischen die tr und td Elemente einer Tabelle enthält. Wenn Ihr Skript ausgeführt wird, werden diese Textknoten zu Abschnitten, aber Elemente außerhalb von tr und td Elementen in einer Tabelle dürfen nicht enthalten sein. Dies führt dazu, dass die meisten Browser Phantomspalten automatisch in die Tabelle einfügen, wodurch das Layout durcheinander gebracht wird.

Als eine schnelle Lösung können Sie Textknoten ignorieren, die nur Leerzeichen enthalten. Dies ist trivial zu tun, wenn Sie den TreeWalker API verwenden, um als Filter in der folgenden Funktion übergeben:

node => /\S/.test(node.nodeValue) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT 

Als eine langfristige Lösung, müssen Sie wahrscheinlich durch die HTML5 spec aussehen zu wissen Stellen Sie sicher, welche Elemente Spannungsknoten enthalten dürfen, und schreiben Sie Ihr Skript entsprechend.

+1

Vielen Dank, Ihre Antwort ist richtig! Durch den Ausschluss der Elternelemente TABLE/TBODY/TR/UL/OL ist das Problem beseitigt. Danke noch einmal! –

Verwandte Themen