Javascript - Hängt HTML ohne innerHTML an Containerelement an


167

Ich brauche eine Möglichkeit, HTML an ein Containerelement anzuhängen, ohne innerHTML zu verwenden. Der Grund, warum ich innerHTML nicht verwenden möchte, liegt darin, dass es wie folgt verwendet wird:

element.innerHTML += htmldata

Es funktioniert, indem zuerst der gesamte HTML-Code ersetzt wird, bevor der alte HTML-Code und der neue HTML-Code hinzugefügt werden. Dies ist nicht gut, da dynamische Medien wie eingebettete Flash-Videos zurückgesetzt werden ...

Ich könnte es so machen, was funktioniert:

var e = document.createElement('span');
e.innerHTML = htmldata;
element.appendChild(e);

Das Problem auf diese Weise ist jedoch, dass das Dokument jetzt das zusätzliche Span-Tag enthält, das ich nicht möchte.

Wie kann das dann gemacht werden? Vielen Dank!


1
Warum nicht Jquery verwenden? Überprüfen Sie meine detaillierte Antwort unten. stackoverflow.com/a/50482776/5320562
Loukan ElKadi

Antworten:


102

So geben Sie eine Alternative an (da die Verwendung DocumentFragmentnicht zu funktionieren scheint): Sie können sie simulieren, indem Sie die untergeordneten Elemente des neu generierten Knotens durchlaufen und nur diese anhängen.

var e = document.createElement('div');
e.innerHTML = htmldata;

while(e.firstChild) {
    element.appendChild(e.firstChild);
}

2
Ich dachte, wir suchen nach einer Lösung, die nicht "innerHTML" verwendet
kennydelacruz

1
@kennydelacruz: Das OP wollte keinen neuen HTML- Code an einen vorhandenen HTML- Code anhängen, da die vorhandenen Elemente zerstört und neu erstellt werden. Das OP hat eine Lösung gefunden, indem es ein neues Element erstellt und dieses angehängt hat, aber es wollte kein zusätzliches Element hinzufügen. Ich habe diese Lösung nur erweitert, um zu zeigen, dass sie die neu erstellten Elemente verschieben / anhängen können, was sich nicht auf die vorhandenen Elemente auswirkt.
Felix Kling

Ich weiß, dass dies alt ist, aber kann mir jemand erklären, warum man über e.firstChild iterieren kann?
Toastgeraet

1
@Toastgeraet: Dies ist beispielsweise nicht Iterieren über e.firstChild . Vielmehr wird geprüft, ob eein Kind vorhanden ist, und wenn ja, wird dieses Kind in das Element verschoben .
Felix Kling

570

Ich bin überrascht, dass in keiner der Antworten die insertAdjacentHTML()Methode erwähnt wurde. Schau es dir hier an . Der erste Parameter ist, wo Sie die Zeichenfolge anhängen und nehmen möchten ("beforebegin", "afterbegin", "beforeend", "afterend"). In der Situation des OP würden Sie "beforeend" verwenden. Der zweite Parameter ist nur die HTML-Zeichenfolge.

Grundlegende Verwendung:

var d1 = document.getElementById('one');
d1.insertAdjacentHTML('beforeend', '<div id="two">two</div>');

53
Habe gerade deine Lösung ausprobiert sowie die akzeptierte. Beides funktioniert, aber deins ist nur 2 Zeilen und keine Schleifen. Klingt für mich nach einem Gewinner.
Corwin01

3
Als Hinweis für alle, die diese Route wählen könnten: Diese Methode spielt nicht gut mit Tabellen in IE9.
Corwin01

2
In Chrome sagt es mir Uncaught TypeError: undefined is not a function!
J86

19
Dieses versteckte Juwel braucht mehr Belichtung.
Seth

Sie erhalten eine Fehlermeldung, wenn Sie versuchen, diese Methode für etwas zu verwenden, das kein Knoten ist, sondern nur zu Ihrer Information.
Alex W

15

alnafie hat eine gute Antwort auf diese Frage. Ich wollte ein Beispiel seines Codes als Referenz geben:

var childNumber = 3;

function addChild() {
  var parent = document.getElementById('i-want-more-children');
  var newChild = '<p>Child ' + childNumber + '</p>';
  parent.insertAdjacentHTML('beforeend', newChild);
  childNumber++;
}
body {
  text-align: center;
}
button {
  background: rgba(7, 99, 53, .1);
  border: 3px solid rgba(7, 99, 53, 1);
  border-radius: 5px;
  color: rgba(7, 99, 53, 1);
  cursor: pointer;
  line-height: 40px;
  font-size: 30px;
  outline: none;
  padding: 0 20px;
  transition: all .3s;
}
button:hover {
  background: rgba(7, 99, 53, 1);
  color: rgba(255,255,255,1);
}
p {
  font-size: 20px;
  font-weight: bold;
}
<button type="button" onclick="addChild()">Append Child</button>
<div id="i-want-more-children">
  <p>Child 1</p>
  <p>Child 2</p>
</div>

Hoffentlich ist dies für andere hilfreich.


2
Ich hasse es, ein Verfechter der Regeln zu sein, aber ich denke, es wäre besser gewesen, wenn Sie eine Demo (jsfiddle, codepen usw.) erstellt und diese dann zu Alnafies Antwort hinzugefügt hätten, indem Sie die Bearbeitungsfunktion verwendet oder einen Kommentar abgegeben hätten. Wenn Sie nur eine Antwort erstellen, um die Antwort eines anderen Benutzers zu demonstrieren, funktioniert SO nicht, unabhängig davon, wie nützlich die von Ihnen angegebenen Informationen sind. Stellen Sie sich vor, jeder Benutzer würde eine andere Antwort durch Erstellen einer Antwort demonstrieren - es würde chaotisch werden.
Martin James

2
<div id="Result">
</div>

<script>
for(var i=0; i<=10; i++){
var data = "<b>vijay</b>";
 document.getElementById('Result').innerHTML += data;
}
</script>

Weisen Sie die Daten für div mit dem Symbol "+ =" zu. Sie können Daten einschließlich vorheriger HTML-Daten anhängen


11
Die Frage erfordert ausdrücklich nicht zu verwenden element.innerHTML += data.
musicnothing

1

Dafür DocumentFragmentwar gedacht.

var frag = document.createDocumentFragment();
var span = document.createElement("span");
span.innerHTML = htmldata;
for (var i = 0, ii = span.childNodes.length; i < ii; i++) {
    frag.appendChild(span.childNodes[i]);
}
element.appendChild(frag);

document.createDocumentFragment, .childNodes


Ich habe das gerade getestet und es funktioniert nicht. Sollte es so verwendet werden?
Bob

Woher kommst du (a)? Ist das ein Tippfehler?
Ash Burlaczenko

1
Ja das ist ein Tippfehler, es sollte e sein. Ich glaube nicht, dass Sie innerHTML für ein Fragment verwenden können. Dies funktioniert nicht
Bob

@ Bob Ich habe mich für die Copout-Verwendung von jQuery entschieden.
Raynos

jQuery nein nein! Ich werde jQuery nicht nur für eine kleine Funktion einschließen: \ Es ist nur übertrieben
Bob

-1

Wie man fischt und dabei strengen Code verwendet. Am Ende dieses Beitrags sind zwei vorausgesetzte Funktionen erforderlich.

xml_add('before', id_('element_after'), '<span xmlns="http://www.w3.org/1999/xhtml">Some text.</span>');

xml_add('after', id_('element_before'), '<input type="text" xmlns="http://www.w3.org/1999/xhtml" />');

xml_add('inside', id_('element_parent'), '<input type="text" xmlns="http://www.w3.org/1999/xhtml" />');

Fügen Sie mehrere Elemente hinzu (der Namespace muss sich nur im übergeordneten Element befinden):

xml_add('inside', id_('element_parent'), '<div xmlns="http://www.w3.org/1999/xhtml"><input type="text" /><input type="button" /></div>');

Dynamisch wiederverwendbarer Code:

function id_(id) {return (document.getElementById(id)) ? document.getElementById(id) : false;}

function xml_add(pos, e, xml)
{
 e = (typeof e == 'string' && id_(e)) ? id_(e) : e;

 if (e.nodeName)
 {
  if (pos=='after') {e.parentNode.insertBefore(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e.nextSibling);}
  else if (pos=='before') {e.parentNode.insertBefore(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e);}
  else if (pos=='inside') {e.appendChild(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true));}
  else if (pos=='replace') {e.parentNode.replaceChild(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e);}
  //Add fragment and have it returned.
 }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.