2013-07-10 11 views
12

Tworzę edytor HTML w czasie rzeczywistym, który ładuje się po wyrenderowaniu DOM i buduje źródło, przechodząc przez wszystkie węzły. Zauważyłem, że gdy próbuję odczytać nodeValue węzła tekstowego zawierającego encję HTML, zawsze otrzymuję renderowaną wartość Unicode tej encji.tekst nodeValue zawierający encję HTML

Jak mogę odczytać węzeł renderowanego tekstu i zachować kod jednostki HTML? (Przy użyciu wanilia JS)

Przykład:

<div id="test">copyright &copy;</div> 
<script> 
var test = document.getElementById('test'); 
console.log(test.childNodes[0].nodeValue); 
// expected: copyright &copy; 
// actual: copyright © 
</script> 

Odpowiedz

6

Niestety nie można. Interfejs Text dziedziczy CharacterData i oba interfejsy zapewniają tylko DOMStrings jako wartości zwracanej, który zawiera znaki Unicode.

Ponadto algorytm analizy parsowania HTML5 zasadniczo usuwa encję w całości. Jest to zdefiniowane w kilku sekcjach 8.2.4 Tokenization.

  • 8.2.4.1 stan danych: opisuje, że ampersand stawia parser do odniesienia postać w stanie danych
  • 8.2.4.2 odniesienia w postaci stanu danych opisuje, że żetony następnie przez znak ampersand powinien zostać skonsumowany. Jeśli wszystko działa poprawnie, zwróci tokeny znaków Unicode, a nie encję!
  • 8.2.4.69 Referencje znaków Tokenizing opisuje, jak interpretować &...; (w zasadzie zrobić pewne rzeczy i jeśli wszystko jest w porządku, look it up in the table).

Tak więc przed zakończeniem pracy nad parserem obiekt już zniknął i został zastąpiony symbolami Unicode. To nie jest takie zaskakujące, ponieważ możesz również umieścić symbol © bezpośrednio w kodzie HTML, jeśli chcesz.

Jednak nadal można cofnąć tej transformacji: trzeba wziąć kopię table, i sprawdzić, czy znak w dokumencie, czy posiada wpis w nim:

var entityTable = { 
    169: "&copy;" 
} 

function reEntity(character){ 
    var index = character.charCodeAt(0), name; 

    if(index < 127) // ignore ASCII symbols 
    return character; 

    if(entityTable[index]) { 
    name = entityTable[index]; 
    } else { 
    name = "#"+index; 
    } 
    return "&"+name+";" 
} 

Jest to dość niewygodne zadanie, ale z powodu zachowania parsera prawdopodobnie musisz to zrobić. (Nie zapomnij sprawdzić, czy ktoś już to zrobił).

+0

To trochę rozczarowuje. Po prostu skorzystam ze stołu i zdobędę auto-uzupełnienie. – Shea

+0

Wygląda na to, że istnieją wyjątki typu ' ': Ciąg znaków 6-znakowy pojawia się podczas wywoływania '.innerHTML' na elementach. Spróbuj: 'd = document.createElement (" i "); d.innerHTML = ' '; console.log (d.innerHTML) ' –