Inserimento di elementi HTML con JavaScript


105

Invece di cercare noiosamente soluzioni alternative per ogni tipo di attributo ed evento quando si utilizza la seguente sintassi:

elem = document.createElement("div");
elem.id = 'myID';
elem.innerHTML = ' my Text '
document.body.insertBefore(elem,document.body.childNodes[0]);

C'è un modo in cui posso semplicemente dichiarare l'intero elemento HTML come una stringa? piace:

elem = document.createElement("<div id='myID'> my Text </div>");
document.body.insertBefore(elem,document.body.childNodes[0]);

Risposte:


124

Invece di scherzare direttamente con innerHTMLesso potrebbe essere meglio creare un frammento e quindi inserirlo:

function create(htmlStr) {
    var frag = document.createDocumentFragment(),
        temp = document.createElement('div');
    temp.innerHTML = htmlStr;
    while (temp.firstChild) {
        frag.appendChild(temp.firstChild);
    }
    return frag;
}

var fragment = create('<div>Hello!</div><p>...</p>');
// You can use native DOM methods to insert the fragment:
document.body.insertBefore(fragment, document.body.childNodes[0]);

Benefici:

  1. Puoi utilizzare metodi DOM nativi per l'inserimento come insertBefore, appendChild ecc.
  2. Hai accesso ai nodi DOM effettivi prima che vengano inseriti; puoi accedere all'oggetto childNodes del frammento.
  3. L'utilizzo dei frammenti di documenti è molto veloce; più veloce della creazione di elementi al di fuori del DOM e in determinate situazioni più veloce di innerHTML.

Anche se innerHTMLviene utilizzato all'interno della funzione, accade tutto al di fuori del DOM, quindi è molto più veloce di quanto si pensi ...


3
Scommetto che createDocumentFragment () non sarebbe buono come il "legacy" innerHTML.
TheFlash

2
Questo metodo funziona in tutti i browser moderni. Per IE 5.5 e versioni precedenti è possibile eseguire un controllo come :: if (document.createDocumentFragment) {create ('...'); } else {/ * Usa innerHTML forse * /}
James,

32
crescentfresh, aiuto in SO perché mi piace aiutare le persone; Mi dispiace se una soluzione non è utilizzabile al 100% in tutte le situazioni. Se sei così preoccupato, perché non offrire la tua soluzione invece di essere inutilmente critico nei confronti delle risposte già offerte? Con qualsiasi astrazione ci saranno sempre casi limite! Questo è un ambiente di apprendimento - non siamo qui per dare alle persone una soluzione su un piatto - siamo qui per aiutarci a vicenda a migliorare ciò che facciamo! E scusate, ma dove qualcuno ha parlato di "AJAX"?
James

1
Giusto. Mie scuse. Sento solo che ci sono così tante astrazioni qui con zero avvertimenti menzionati.
Crescent Fresh

1
questo è molto più complesso di quanto dovrebbe essere - la risposta di sime vidas è molto meglio
JonnyRaa

83

Tu vuoi questo

document.body.insertAdjacentHTML( 'afterbegin', '<div id="myID">...</div>' );

13
non sono sicuro del motivo per cui questa non è la risposta accettata. Questo è molto più semplice e ovviamente corretto
JonnyRaa

@ JonnyLeeds questo non sembra funzionare bodysull'elemento ma funziona bene su qualsiasi altro elemento.
Phill

1
@Phill Ovviamente funziona <body>. È un dato di fatto, eseguirlo è il <body>mio metodo standard per iniettare cose come i fogli di stile nelle pagine web tramite la console. Che problema stai riscontrando?
Šime Vidas

@ ŠimeVidas probabilmente perché l'elemento body non è stato definito al momento dell'esecuzione ... ho accoppiato la tua linea con window.onload = function () {…} per evitare quel problema
GDY

@Grandy Phill ha scritto che funziona su altri elementi. Se <body>non fosse definito, lo sarebbero anche tutti gli altri elementi, quindi questo probabilmente non è un problema di Phill.
Šime Vidas

32

Dai un'occhiata a insertAdjacentHTML

var element = document.getElementById("one");
var newElement = '<div id="two">two</div>'
element.insertAdjacentHTML( 'afterend', newElement )
// new DOM structure: <div id="one">one</div><div id="two">two</div>

posizione è la posizione relativa all'elemento che stai inserendo adiacente a:

'beforebegin' Prima dell'elemento stesso

'afterbegin' Appena dentro l'elemento, prima del suo primo figlio

'beforeend' Appena dentro l'elemento, dopo il suo ultimo figlio

'afterend' Dopo l'elemento stesso


17

Nella vecchia scuola JavaScript, potresti fare questo:

document.body.innerHTML = '<p id="foo">Some HTML</p>' + document.body.innerHTML;

In risposta al tuo commento:

[...] Ero interessato a dichiarare la fonte degli attributi e degli eventi di un nuovo elemento, non la fonte innerHTMLdi un elemento.

Tuttavia, è necessario inserire il nuovo HTML nel DOM; ecco perché innerHTMLviene utilizzato nell'esempio JavaScript della vecchia scuola. Il innerHTMLdel BODYelemento viene anteposto con il nuovo HTML. Non stiamo realmente toccando l'HTML esistente all'interno del file BODY.

Riscriverò l'esempio di cui sopra per chiarire questo:

var newElement = '<p id="foo">This is some dynamically added HTML. Yay!</p>';
var bodyElement = document.body;
bodyElement.innerHTML = newElement + bodyElement.innerHTML;
// note that += cannot be used here; this would result in 'NaN'

L'uso di un framework JavaScript renderebbe questo codice molto meno dettagliato e migliorerebbe la leggibilità. Ad esempio, jQuery ti consente di fare quanto segue:

$('body').prepend('<p id="foo">Some HTML</p>');

Piuttosto buono. Ma ero interessato a dichiarare l'origine degli attributi e degli eventi di un nuovo elemento, non l'internoHTML di un elemento.
TheFlash

1
document.getElementsByTagName('body')[0]può effettivamente essere sostituito da document.body, buon punto. Tuttavia, se vuoi anteporre o aggiungere il nuovo HTML a un altro elemento esistente invece che a BODY, dovrai usare document.getElementById()e / o document.getElementsByTagName(); ecco perché l'ho usato nell'esempio.
Mathias Bynens

1
Inoltre, il tuo codice può diventare molto disordinato molto rapidamente se stai aggiungendo / inserendo direttamente "innerHTML"
James,

1
@ JimmyP: Che schifezza! Lo scopo stesso di questa domanda è quello di poter inserire direttamente HTML come stringhe invece di giocare con le funzioni per costruirlo, attrib per attrib, nodo per nodo, elemento per elemento.
TheFlash

1
questo scollega tutti i gestori di eventi e può causare grandi perdite di memoria.
adardesign

1

Per quanto ne so, che, ad essere onesti, è abbastanza nuovo e limitato, l'unico potenziale problema con questa tecnica è il fatto che ti viene impedito di creare dinamicamente alcuni elementi di tabella.

Uso un modulo per creare modelli aggiungendo elementi "modello" a un DIV nascosto e quindi utilizzando cloneNode (true) per creare un clone e aggiungerlo come richiesto. Tieni presente che devi assicurarti di riassegnare gli ID come richiesto per evitare la duplicazione.


-1

Come altri hanno detto, la comoda funzionalità jQuery prepend può essere emulata:

var html = '<div>Hello prepended</div>';
document.body.innerHTML = html + document.body.innerHTML;

Mentre alcuni dicono che è meglio non "confondere" con innerHTML , è affidabile in molti casi d'uso, se sai questo:

Se un <div>, <span>o <noembed>nodo ha un nodo figlio testo che include i caratteri ( &), ( <) o ( >), innerHTML restituisce questi personaggi come &amp, &lte &gt, rispettivamente. Utilizzare Node.textContentper ottenere una copia corretta del contenuto di questi nodi di testo.

https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML

O:

var html = '<div>Hello prepended</div>';
document.body.insertAdjacentHTML('afterbegin', html)

insertAdjacentHTMLè probabilmente una buona alternativa: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML


-2

Se vuoi inserire codice HTML all'interno del tag di una pagina esistente usa Jnerator . Questo strumento è stato creato appositamente per questo obiettivo.

Invece di scrivere il codice successivo

    var htmlCode = '<ul class=\'menu-countries\'><li
        class=\'item\'><img src=\'au.png\'></img><span>Australia </span></li><li
        class=\'item\'><img src=\'br.png\'> </img><span>Brazil</span></li><li
        class=\'item\'> <img src=\'ca.png\'></img><span>Canada</span></li></ul>';
    var element = document.getElementById('myTag');
    element.innerHTML = htmlCode;

Puoi scrivere una struttura più comprensibile

    var jtag = $j.ul({
        class: 'menu-countries',
        child: [
            $j.li({ class: 'item', child: [
                $j.img({ src: 'au.png' }),
                $j.span({ child: 'Australia' })
            ]}),
            $j.li({ class: 'item', child: [
                $j.img({ src: 'br.png' }),
                $j.span({ child: 'Brazil' })
            ]}),
            $j.li({ class: 'item', child: [
                $j.img({ src: 'ca.png' }),
                $j.span({ child: 'Canada' })
            ]})
        ]
    });
    var htmlCode = jtag.html();
    var element = document.getElementById('myTag');
    element.innerHTML = htmlCode;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.