jQuery document.createElement equivalente?


1251

Sto refactoring del vecchio codice JavaScript e c'è molta manipolazione DOM in corso.

var d = document;
var odv = d.createElement("div");
odv.style.display = "none";
this.OuterDiv = odv;

var t = d.createElement("table");
t.cellSpacing = 0;
t.className = "text";
odv.appendChild(t);

Vorrei sapere se esiste un modo migliore per farlo usando jQuery. Ho sperimentato con:

var odv = $.create("div");
$.append(odv);
// And many more

Ma non sono sicuro che sia meglio.


jsben.ch/#/ARUtz - un punto di riferimento per jquery vs createElement
EscapeNetscape


Uncaught TypeError: $ .create non è una funzione
Tyguy7

Risposte:


1290

Ecco il tuo esempio nella riga "one".

this.$OuterDiv = $('<div></div>')
    .hide()
    .append($('<table></table>')
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;

Aggiornamento : ho pensato di aggiornare questo post poiché riceve ancora un bel po 'di traffico. Nei commenti qui sotto c'è qualche discussione su $("<div>")vs $("<div></div>")vs $(document.createElement('div'))come un modo per creare nuovi elementi, e che è "il migliore".

Ho messo insieme un piccolo benchmark e qui ci sono circa i risultati della ripetizione delle opzioni di cui sopra 100.000 volte:

jQuery 1.4, 1.5, 1.6

               Chrome 11  Firefox 4   IE9
<div>            440ms      640ms    460ms
<div></div>      420ms      650ms    480ms
createElement    100ms      180ms    300ms

jQuery 1.3

                Chrome 11
<div>             770ms
<div></div>      3800ms
createElement     100ms

jQuery 1.2

                Chrome 11
<div>            3500ms
<div></div>      3500ms
createElement     100ms

Penso che non sia una grande sorpresa, ma document.createElementè il metodo più veloce. Ovviamente, prima di partire e iniziare a refactoring dell'intera base di codice, ricorda che le differenze di cui stiamo parlando qui (in tutte le versioni tranne quelle arcaiche di jQuery) equivalgono a circa 3 millisecondi in più per mille elementi .


Aggiornamento 2

Aggiornato per jQuery 1.7.2 e metti il ​​benchmark su JSBen.chcui probabilmente è un po 'più scientifico dei miei benchmark primitivi, in più può essere ora crowdsourcing!

http://jsben.ch/#/ARUtz


70
Scoprirai che document.createElement è molto più veloce di avere jQuery che converte la tua stringa HTML in un elemento. (nel caso abbiate un bisogno di rendere le cose più efficienti)
Sugendran

25
Questo è vero per jQuery <1.3 È l'equivalente di velocità ora credo.
Rob Stevenson-Leggett,

15
@Kevin, è vero, tuttavia fa sì che jQuery faccia più lavoro (lo esegue attraverso una regex per aggiungere il tag di chiusura), quindi preferisco il metodo sopra. Inoltre, differenzia il tuo codice dal $('div')quale è visivamente molto simile, ma funzionalmente a parte i poli.
nickf

14
Quindi sostanzialmente una combinazione di @Sungendran e @nickf sarebbe $(document.createElement('div'))e dovrebbe essere la più veloce?
Kolky,

14
Penso che il modo "corretto" sia $ ('<div />'), con, IMO, ha ancora più "significato", dato che è abbastanza ovvio che stai creando un Nodo. La cosa brutta è che in questo modo si interrompe l'evidenziazione della sintassi in tutti gli editor = (
Erik Escobedo

139

Fornire semplicemente l'HTML degli elementi che si desidera aggiungere a un costruttore jQuery $()restituirà un oggetto jQuery da HTML di nuova costruzione, adatto per essere aggiunto al DOM usando il append()metodo jQuery .

Per esempio:

var t = $("<table cellspacing='0' class='text'></table>");
$.append(t);

È quindi possibile popolare questa tabella a livello di codice, se lo si desidera.

Ciò ti dà la possibilità di specificare qualsiasi HTML arbitrario che ti piace, inclusi nomi di classe o altri attributi, che potresti trovare più conciso rispetto all'utilizzo createElemente all'impostazione di attributi come cellSpacinge classNametramite JS.


7
Forse questo era ovvio e indicato dal tuo esempio, ma la creazione di un elemento DOM jQuery usando la sintassi $ ("<html string>"), non può essere aggiunta al DOM usando il metodo nativo <element> .appendChild o simile. È necessario utilizzare il metodo di aggiunta jQuery.
Adam,

4
$(htmlStr)è implementato come document.createElement("div").innerHTML = htmlStr. In altre parole, richiama il parser HTML del browser. HTML non corretto si rompe in modo diverso in Internet Explorer rispetto ad altri browser.
Matthew

2
@Adam L'oggetto jQuery ha la getfunzione che restituisce l'elemento DOM nativo. (So ​​che questo argomento è vecchio, ma lo aggiungo come riferimento. ;-))
Constantino Tsarouhas,


1
@Adam Oppure, se è più semplice il flusso / gli occhi del codice, puoi farlo[dom element].appendChild($('<html>')[0]);
ACK_stoverflow


49

Sto facendo così:

$('<div/>',{
    text: 'Div text',
    class: 'className'
}).appendTo('#parentDiv');

44

poiché jQuery1.8, usare $.parseHTML()per creare elementi è una scelta migliore.

ci sono due vantaggi:

1.Se usi il vecchio modo, che potrebbe essere qualcosa del genere $(string), jQuery esaminerà la stringa per assicurarti di voler selezionare un tag html o creare un nuovo elemento. Usando $.parseHTML(), dici a jQuery che vuoi creare esplicitamente un nuovo elemento, quindi le prestazioni potrebbero essere leggermente migliori.

2.La cosa molto più importante è che potresti soffrire di attacchi incrociati ( maggiori informazioni ) se usi la vecchia maniera. se hai qualcosa come:

    var userInput = window.prompt("please enter selector");
    $(userInput).hide();

un cattivo può inserire <script src="xss-attach.js"></script>per prenderti in giro. per fortuna, $.parseHTML()evita questo imbarazzo per te:

var a = $('<div>')
// a is [<div>​</div>​]
var b = $.parseHTML('<div>')
// b is [<div>​</div>​]
$('<script src="xss-attach.js"></script>')
// jQuery returns [<script src=​"xss-attach.js">​</script>​]
$.parseHTML('<script src="xss-attach.js"></script>')
// jQuery returns []

Tuttavia, si noti che aè un oggetto jQuery mentre bè un elemento html:

a.html('123')
// [<div>​123​</div>​]
b.html('123')
// TypeError: Object [object HTMLDivElement] has no method 'html'
$(b).html('123')
// [<div>​123​</div>​]

La "scelta migliore" per "creare [qualsiasi] elemento" potrebbe essere forte. La risposta di @ siergiej fa un buon lavoro nel dire che parseHTMLva bene per HTML proveniente da fonti esterne, ma che " tutto il boost è andato dopo aver avvolto i risultati in un nuovo oggetto jQuery ". Cioè, se vuoi codificare la creazione di un nuovo elemento html avvolto in jQuery, lo $("<div>stuff</div>")stile sembra comunque vincere.
ruffin,

38

AGGIORNARE

A partire dalle ultime versioni di jQuery, il seguente metodo non assegna le proprietà passate nel secondo oggetto

Risposta precedente

Mi sento che usare document.createElement('div')insieme jQueryè più veloce:

$(document.createElement('div'), {
    text: 'Div text',
    'class': 'className'
}).appendTo('#parentDiv');

29

Sebbene questa sia una domanda molto antica, ho pensato che sarebbe stato bello aggiornarla con informazioni recenti;

Da jQuery 1.8 esiste una funzione jQuery.parseHTML () che è ora un modo preferito di creare elementi. Inoltre, ci sono alcuni problemi con l'analisi dell'HTML tramite $('(html code goes here)'), ad esempio il sito Web ufficiale di jQuery menziona quanto segue in una delle loro note di rilascio :

Analisi HTML rilassata: puoi ancora una volta avere spazi iniziali o nuove righe prima dei tag in $ (htmlString). Si consiglia comunque vivamente di utilizzare $ .parseHTML () durante l'analisi dell'HTML ottenuto da fonti esterne e potrebbe essere necessario apportare ulteriori modifiche all'analisi dell'HTML in futuro.

Per fare riferimento alla domanda effettiva, a condizione che l'esempio possa essere tradotto in:

this.$OuterDiv = $($.parseHTML('<div></div>'))
    .hide()
    .append($($.parseHTML('<table></table>'))
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;

che sfortunatamente è meno conveniente rispetto all'uso di just $(), ma ti dà più controllo, ad esempio puoi scegliere di escludere i tag di script (lascerà gli script in linea come onclickse):

> $.parseHTML('<div onclick="a"></div><script></script>')
[<div onclick=​"a">​</div>​]

> $.parseHTML('<div onclick="a"></div><script></script>', document, true)
[<div onclick=​"a">​</div>​, <script>​</script>​]

Inoltre, ecco un punto di riferimento dalla risposta principale adattato alla nuova realtà:

JSbin Link

jQuery 1.9.1

  $ .parseHTML: 88ms
  $ ($. parseHTML): 240 ms
  <div> </div>: 138ms
  <div>: 143ms
  createElement: 64ms

Sembra che parseHTMLsia molto più vicino createElementdi così $(), ma tutta la spinta è sparita dopo aver avvolto i risultati in un nuovo oggetto jQuery



6
var div = $('<div/>');
div.append('Hello World!');

È il modo più breve / più semplice per creare un elemento DIV in jQuery.


5

Ho appena creato un piccolo plugin jQuery per questo: https://github.com/ern0/jquery.create

Segue la tua sintassi:

var myDiv = $.create("div");

L'ID nodo DOM può essere specificato come secondo parametro:

var secondItem = $.create("div","item2");

È serio? No. Ma questa sintassi è migliore di $ ("<div> </div>") ed è un ottimo valore per quel denaro.

Sono un nuovo utente jQuery, passando da DOMAssistant, che ha una funzione simile: http://www.domassistant.com/documentation/DOMAssistantContent-module.php

Il mio plugin è più semplice, penso che attrs e il contenuto sia meglio aggiungere concatenando metodi:

$("#container").append( $.create("div").addClass("box").html("Hello, world!") );

Inoltre, è un buon esempio per un semplice plugin jQuery (il 100 °).


4

È tutto abbastanza semplice! Ecco alcuni esempi rapidi ...


var $example = $( XMLDocRoot );

var $element = $( $example[0].createElement('tag') );
// Note the [0], which is the root

$element.attr({
id: '1',
hello: 'world'
});

var $example.find('parent > child').append( $element );

1

Non menzionato nelle risposte precedenti, quindi sto aggiungendo un esempio funzionante su come creare elementi di elementi con l'ultimo jQuery, anche con attributi aggiuntivi come contenuto, classe o callback onclick:

const mountpoint = 'https://jsonplaceholder.typicode.com/users'

const $button = $('button')
const $tbody = $('tbody')

const loadAndRender = () => {
  $.getJSON(mountpoint).then(data => {

    $.each(data, (index, { id, username, name, email }) => {
      let row = $('<tr>')
        .append($('<td>', { text: id }))
        .append($('<td>', {
          text: username,
          class: 'click-me',
          on: {
            click: _ => {
              console.log(name)
            }
          }
        }))
        .append($('<td>', { text: email }))

      $tbody.append(row)
    })

  })
}

$button.on('click', loadAndRender)
.click-me {
  background-color: lightgrey
}
<table style="width: 100%">
  <thead>
    <tr>
      <th>ID</th>
      <th>Username</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
  
  </tbody>
</table>

<button>Load and render</button>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>


-2

jQuery out of the box non ha l'equivalente di createElement. In effetti, la maggior parte del lavoro di jQuery viene eseguita internamente utilizzando innerHTML rispetto alla pura manipolazione DOM. Come ha già detto Adam in questo modo, puoi ottenere risultati simili.

Ci sono anche plugin disponibili che fanno uso del DOM su innerHTML come appendDOM , DOMEC e FlyDOM solo per citarne alcuni. Per quanto riguarda le prestazioni, il jquery nativo è ancora il più performante (principalmente perché utilizza innerHTML)


5
Dovresti aggiornarti. jQuery non usa innerHtml ma analizza la stringa HTML e crea internamente un albero DOM usando document.createElement (). Questo è jQuery di base.
Vincent Robert
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.