2009-04-05 19 views
28

Ich frage mich, ob es eine Möglichkeit gibt, den Text von irgendetwas in HTML zu ändern, ohne innerHTML zu verwenden.Alternative für innerHTML?

Grund Ich frage ist, weil es vom W3C irgendwie verpönt ist. Ich weiß, es ist pingelig, aber ich will nur wissen, gibt es einen Weg?

EDIT: Leute scheinen zu missverstehen, was ich hier frage: Ich möchte einen Weg finden, den angezeigten Text effektiv zu ändern.

Wenn ich habe:

<div id="one">One</a> 

innerHTML- ermöglicht es mir, dies zu tun:

var text = document.getElementsById("one"); 
text.innerHTML = "Two"; 

Und der Text auf meinem Bildschirm verändert haben.
Ich möchte keinen weiteren Text anhängen, ich möchte bereits vorhandenen Text ändern.

+6

FYI: innerHTML- ist extrem schneller im Vergleich DOM create zu verwenden, createTextNode usw. Efficency Überlegung: http://www.quirksmode.org/dom/ innerhtml.html Außerdem ist innerHTML Teil von HTML5! –

+0

@Marco Was meinst du, wenn du sagst, dass innerHTML Teil von HTML5 ist? – Pacerier

+0

@Pacerier: innerHTML funktioniert in allen Browsern, aber es ist nicht Teil der W3C HTML4.1-Standards (und WebDevHobo sagt, dass dies verpönt). Whistest innerHTML soll Teil des HTML5 sein: http://www.w3.org/TR/2011/WD-html5-diff-20110113/#htmldocument-extensions –

Antwort

29

Der empfohlene Weg ist durch DOM-Manipulation, aber es kann ziemlich ausführlich sein. Zum Beispiel:

// <p>Hello, <b>World</b>!</p> 
var para = document.createElement('p'); 
para.appendChild(document.createTextNode('Hello, ')); 

// <b> 
var b = document.createElement('b'); 
b.appendChild(document.createTextNode('World'); 
para.appendChild(b); 

para.appendChild(document.createTextNode('!')); 

// Do something with the para element, add it to the document, etc. 

EDIT

Als Antwort auf Ihre bearbeiten, um den aktuellen Inhalt zu ersetzen, entfernen Sie einfach den vorhandenen Inhalt, dann verwenden Sie den Code oben in neuen Inhalten zu füllen. Zum Beispiel:

var someDiv = document.getElementById('someID'); 
var children = someDiv.childNodes; 
for(var i = 0; i < children.length; i++) 
    someDiv.removeChild(children[i]); 

Aber als jemand anderes gesagt, ich würde empfehlen, stattdessen so etwas wie jQuery verwenden, da nicht alle Browser vollständig DOM unterstützen, und diejenigen, die zu tun haben Macken, die mit intern von JavaScript-Bibliotheken behandelt werden. Zum Beispiel sieht jQuery etwas wie folgt aus:

$('#someID').html("<p>Hello, <b>World</b>!</p>"); 
+0

so tatsächlich, erst Platz neuen Text und dann entfernen alt ... das scheint eine sehr längliche Möglichkeit, Dinge zu tun ... Ich frage mich, warum das W3C nicht von innerHTML Ihre Ansicht ist das mit. – KdgDev

+2

innerHTML ist es möglich, ein ungültiges Markup in ein XML/XHTML-Dokument einzufügen. Trotzdem scheinen sie ihre Meinung mit HTML5 geändert zu haben. – Turnor

+12

jQuery verwendet innerHTML viele Male im Code, daher wird empfohlen, jQuery zu verwenden, um die Verwendung von innerHTML zu vermeiden, macht IMHO keinen Sinn. –

10

Der bessere Weg, es zu tun ist, document.createTextNode zu verwenden. Einer der Hauptgründe für die Verwendung dieser Funktion anstelle von innerHTML ist, dass alle HTML-Zeichen-Escaping für Sie erledigt werden, während Sie Ihre Zeichenfolge selbst entkommen müssten, wenn Sie einfach innerHTML setzen.

+3

Es scheint jedoch, dass innerHTML viel schneller als die W3C DOM-Methoden ist: http://www.quirksmode.org/dom/innerhtml.html. –

+3

Es hängt davon ab, was Sie tun; Es ist irreführend zu sagen, dass eine Methode besser ist. DOM tendiert dazu, langsamer zu werden, wenn childNode-Operationen für viele Elemente ausgeführt werden (Tendenz zu O (n²)), wobei innerHTML sie alle auf einmal erledigen kann. Der Syntax-/Serialisierungsschritt von innerHTML kann jedoch andere Operationen verlangsamen. – bobince

1

Sie könnten DOM wie folgt verwenden:

<html> 
<body> 
<div>before</div> 
<script type="text/javascript"> 
var element = document.getElementsByTagName("div")[0]; 
alert(element.firstChild.nodeValue); 
element.removeChild(element.firstChild); 
element.appendChild(document.createTextNode('after')); 
alert(element.firstChild.nodeValue); 
</script> 
</body> 

Aber ich denke, jemand dies selten tun, sondern einen Rahmen wie jQuery oder Prototype oder anderen JavaScript-Framework verwenden out there stattdessen. Dies ist jquery Beispiel:

<html> 
<head> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script> 
</head> 
<body> 
<div>before</div> 
<script type="text/javascript"> 
var element = $("div"); 
alert(element.text()); 
element.text("after"); 
alert(element.text()); 
</script> 
</body> 
6

Sie können den gleichen Effekt durch die Manipulation des DOM erhalten. Die sicherste Methode zum Ändern von Text besteht darin, alle untergeordneten Knoten des Elements zu entfernen und sie durch einen neuen Textknoten zu ersetzen.

Durch Entfernen der untergeordneten Knoten wird der Textinhalt Ihres Elements gelöscht, bevor es durch den neuen Text ersetzt wird.

Der Grund, warum die meisten Entwickler die Verwendung von innerHTML vermeiden, besteht darin, dass der Zugriff auf Elemente über das DOM standardkonform ist.

6

Wenn Sie nur Klartext ändern wollen, dann gibt es eine schnellere Lösung, die auf Standards basiert: Wie auch immer

document.getElementById("one").firstChild.data = "two"; 

Bitte beachten Sie, dass innerHTML- Teil des kommenden HTML 5 Standard sein wird. der Text des Stils und der Script-Elemente

+0

Das funktioniert nur, wenn es bereits einen Childnode gibt. –

2
var who=document.getElementById('one'), txt='new text'; 
if(who.innerText) who.innerText=txt; 
else if(who.textContent) who.textContent= txt; 

Dies kann als anstößig als innerHTML- Ihnen sein, aber es hat den Vorteil, in einigen Fällen (IE) zu arbeiten, wo innerHTML- oder appendChild nicht tun, wie einige Tabellenknoten und der Wert der Formularfelder

1

Es scheint mir, dass die CSS + HTML + JS Kombination gewünschte Effekte erzielen sollte:

.myelement:before { 
    content: attr(alt); 
} 

... 

<span class='myelement' alt='initial value'></span> 

... 

element.setAttribute('alt', 'new value'); 

Wer weiß, ob dies in der Praxis funktioniert?

4

Einfach.

Ersetzen Sie text.innerHTML = 'two' durch text.firstChild.nodeValue = 'two'.

+1

Ja! Und [ist 20x schneller] (http://stackoverflow.com/a/18418270/287948)! –

1

Nun, ich verstehe Ihre Frage richtig das sollte eine Antwort sein.

var text = document.getElementById("one"); 
//text.innerHTML = "Two"; 
text.childNodes[0].nodeValue="two"; 
0

Manchmal finde ich es hilfreich, einen direkten Verweis auf den Textknoten zu speichern, wenn ich ihn regelmäßig aktualisiere. Ich mache so etwas wie diese:

var dynamicText = myDiv.appendChild(document.createTextNode("the initial text")); 

Und dann, wenn ich es aktualisieren müssen, ich dies nur tun:

dynamicText.nodeValue = "the updated text"; 

Dies verhindert, die den DOM zu gehen oder addieren oder Kinder zu entfernen.

1

auch auf der Suche nach einer guten Alternative element.innerHTML zu umgehen Schließlich fand ich, dass die Lösung:

HTMLElement.prototype.htmlContent = function(html) 
{ 
    var dom = new DOMParser().parseFromString('<template>'+html+'</template>', 'text/html').head; 
    this.appendChild(dom.firstElementChild.content); 
} 

//-- document.getElementById('my-id').innerHTML = string_of_html; 
document.getElementById('my-id').htmlContent(string_of_html); 

Eine weitere Alternative ohne <Vorlage> Tags, aber Schleife statt:

HTMLElement.prototype.htmlContent = function(html) 
{ 
    var dom = new DOMParser().parseFromString(html, 'text/html').body; 
    while (dom.hasChildNodes()) this.appendChild(dom.firstChild); 
} 

Beachten Sie, dass diese Methode tatsächlich 'Inhalt' hinzufügen, wenn innerHTML 'Inhalt ersetzen' ...

Dies kann helfen:

HTMLElement.prototype.clearContent = function() 
{ 
    while (this.hasChildNodes()) this.removeChild(this.lastChild); 
} 

//-- document.getElementById('my-id').innerHTML = ''; 
document.getElementById('my-id').clearContent(); 

doc: https://github.com/swannty/escaping-innerHTML
perf: https://jsperf.com/escaping-innerhtml