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!

Bob
quelle
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);
}
Felix Kling
quelle
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>');
Alnafie
quelle
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.

Trevor Nestman
quelle
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

Vijay
quelle
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

Raynos
quelle
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.
 }
}
John
quelle