Setara dengan dokumen jQuery.createElement?

1251

Saya refactoring beberapa kode JavaScript lama dan ada banyak manipulasi DOM yang terjadi.

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);

Saya ingin tahu apakah ada cara yang lebih baik untuk melakukan ini menggunakan jQuery. Saya telah bereksperimen dengan:

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

Tetapi saya tidak yakin apakah ini lebih baik.

Rob Stevenson-Leggett
sumber
jsben.ch/#/ARUtz - patokan untuk jquery vs
createElement
Kemungkinan rangkap dari Menciptakan elemen div di jQuery
T.Todua
Uncaught TypeError: $ .create bukan fungsi
Tyguy7

Jawaban:

1290

Inilah contoh Anda di baris "satu".

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

Pembaruan : Saya pikir saya akan memperbarui posting ini karena masih mendapat sedikit lalu lintas. Dalam komentar di bawah ini ada beberapa diskusi tentang $("<div>")vs $("<div></div>")vs $(document.createElement('div'))sebagai cara membuat elemen baru, dan mana yang "terbaik".

Saya mengumpulkan patokan kecil , dan di sini kira-kira hasil mengulangi opsi di atas 100.000 kali:

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

Saya pikir ini bukan kejutan besar, tetapi document.createElementmetode tercepat. Tentu saja, sebelum Anda pergi dan mulai refactoring seluruh basis kode Anda, ingatlah bahwa perbedaan yang kita bicarakan di sini (dalam semua kecuali versi kuno dari jQuery) menyamakan sekitar 3 milidetik per seribu elemen tambahan .


Perbarui 2

Diperbarui untuk jQuery 1.7.2 dan menempatkan patokan JSBen.chyang mungkin sedikit lebih ilmiah daripada tolok ukur primitif saya, ditambah lagi dapat crowdsourced sekarang!

http://jsben.ch/#/ARUtz

nickf
sumber
70
Anda akan menemukan bahwa document.createElement jauh lebih cepat daripada meminta jQuery mengonversi string html Anda menjadi sebuah elemen. (Kalau-kalau Anda memiliki keinginan untuk membuat hal-hal lebih efisien)
Sugendran
25
Itu berlaku untuk jQuery <1.3 Ini setara dengan kecepatan sekarang saya percaya.
Rob Stevenson-Leggett
15
@ Kevin, itu benar, namun itu membuat jQuery melakukan lebih banyak pekerjaan (menjalankannya melalui regex untuk menambahkan tag penutup), jadi saya lebih suka metode di atas. Juga, ini membedakan kode Anda dari $('div')yang secara visual sangat mirip, tetapi secara fungsional terpisah.
nickf
14
Jadi pada dasarnya kombinasi @Sungendran & @nickf akan menjadi $(document.createElement('div'))dan itu harus menjadi yang tercepat?
Kolky
14
Saya pikir cara "benar" adalah $ ('<div />'), dengan, IMO, bahkan memiliki lebih "makna", karena cukup jelas Anda membuat Node. Yang buruk adalah cara ini mematahkan penyorotan sintaks di semua editor = (
Erik Escobedo
139

Cukup dengan menyediakan elemen HTML yang ingin Anda tambahkan ke konstruktor jQuery $()akan mengembalikan objek jQuery dari HTML yang baru dibangun, cocok untuk ditambahkan ke DOM menggunakan append()metode jQuery .

Sebagai contoh:

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

Anda bisa mengisi tabel ini secara terprogram, jika mau.

Ini memberi Anda kemampuan untuk menentukan sembarang HTML yang Anda suka, termasuk nama kelas atau atribut lainnya, yang mungkin Anda temukan lebih ringkas daripada menggunakan createElementdan kemudian menyetel atribut seperti cellSpacingdan classNamemelalui JS.

Adam Bellaire
sumber
7
Mungkin ini sudah jelas, dan ditunjukkan oleh contoh Anda, tetapi membuat elemen DOM jQuery menggunakan sintaks $ ("<html string>"), tidak dapat ditambahkan ke DOM menggunakan metode <element> .appendChild asli atau serupa. Anda harus menggunakan metode append jQuery.
Adam
4
$(htmlStr)diimplementasikan sebagai document.createElement("div").innerHTML = htmlStr. Dengan kata lain, itu memanggil parser HTML browser. HTML yang rusak rusak secara berbeda di IE vs browser lain.
Matius
2
@Adam objek jQuery memiliki getfungsi yang mengembalikan elemen DOM asli. (Saya tahu topik ini sudah lama, tetapi saya menambahkannya untuk referensi. ;-))
Constantino Tsarouhas
1
Jika Anda mengalami masalah dengan string html, coba parsing dengan jQuery.parseHTML
fguillen
1
@ Adam Atau, jika lebih mudah pada aliran kode / mata Anda, Anda dapat melakukannya[dom element].appendChild($('<html>')[0]);
ACK_stoverflow
49

Saya melakukan seperti itu:

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

karena jQuery1.8, menggunakan $.parseHTML()untuk membuat elemen adalah pilihan yang lebih baik.

ada dua manfaat:

1.Jika Anda menggunakan cara lama, yang mungkin seperti $(string), jQuery akan memeriksa string untuk memastikan Anda ingin memilih tag html atau membuat elemen baru. Dengan menggunakan $.parseHTML(), Anda memberi tahu jQuery bahwa Anda ingin membuat elemen baru secara eksplisit, sehingga kinerjanya mungkin sedikit lebih baik.

2.Hal yang lebih penting adalah Anda mungkin menderita serangan lintas situs ( info lebih lanjut ) jika Anda menggunakan cara lama. jika Anda memiliki sesuatu seperti:

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

orang jahat bisa memberi masukan <script src="xss-attach.js"></script>untuk menggoda Anda. untungnya, $.parseHTML()hindari rasa malu ini untuk Anda:

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 []

Namun, harap perhatikan bahwa itu aadalah objek jQuery sementara bmerupakan elemen html:

a.html('123')
// [<div>​123​</div>​]
b.html('123')
// TypeError: Object [object HTMLDivElement] has no method 'html'
$(b).html('123')
// [<div>​123​</div>​]
Brian
sumber
"Pilihan yang lebih baik" untuk "membuat elemen [apa saja]" mungkin kuat. Jawaban @ siergiej melakukan pekerjaan yang baik dengan mengatakan parseHTMLbaik untuk html yang berasal dari sumber eksternal, tetapi bahwa " semua dorongan hilang setelah membungkus hasil dalam objek jQuery baru ". Artinya, jika Anda ingin membuat kode keras pembuatan elemen html baru yang dibungkus jQuery, $("<div>stuff</div>")gaya tampaknya masih menang.
ruffin
38

MEMPERBARUI

Pada versi terbaru jQuery, metode berikut ini tidak menetapkan properti yang diteruskan di Objek kedua

Jawaban sebelumnya

Saya merasa menggunakan document.createElement('div')bersama dengan jQuerylebih cepat:

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

Meskipun ini adalah pertanyaan yang sangat lama, saya pikir akan baik untuk memperbaruinya dengan informasi terbaru;

Sejak jQuery 1.8 ada fungsi jQuery.parseHTML () yang sekarang menjadi cara yang lebih disukai untuk membuat elemen. Juga, ada beberapa masalah dengan parsing HTML via $('(html code goes here)'), misalnya situs web jQuery resmi menyebutkan hal berikut di salah satu catatan rilis mereka :

Penguraian HTML yang rileks: Anda dapat sekali lagi memiliki spasi atau baris baru sebelum tag dalam $ (htmlString). Kami masih sangat menyarankan agar Anda menggunakan $ .parseHTML () saat mem-parsing HTML yang diperoleh dari sumber eksternal, dan mungkin membuat perubahan lebih lanjut ke penguraian HTML di masa mendatang.

Untuk berhubungan dengan pertanyaan aktual, contoh yang diberikan dapat diterjemahkan ke:

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

yang sayangnya kurang nyaman daripada hanya menggunakan $(), tetapi itu memberi Anda lebih banyak kontrol, misalnya Anda dapat memilih untuk mengecualikan tag skrip (itu akan meninggalkan skrip inline seperti onclickmeskipun):

> $.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>​]

Juga, inilah tolok ukur dari jawaban teratas yang disesuaikan dengan kenyataan baru:

Tautan JSbin

jQuery 1.9.1

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

Sepertinya parseHTMLjauh lebih dekat createElementdaripada $(), tetapi semua dorongan hilang setelah membungkus hasil dalam objek jQuery baru

siergiej
sumber
11
var mydiv = $('<div />') // also works
Shimon Doodkin
sumber
6
var div = $('<div/>');
div.append('Hello World!');

Merupakan cara terpendek / termudah untuk membuat elemen DIV di jQuery.

AcidicChip
sumber
5

Saya baru saja membuat plugin jQuery kecil untuk itu: https://github.com/ern0/jquery.create

Ini mengikuti sintaks Anda:

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

ID simpul DOM dapat ditentukan sebagai parameter kedua:

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

Apakah ini serius? Tidak. Tapi sintaks ini lebih baik dari $ ("<div> </div>") , dan itu adalah nilai yang sangat baik untuk uang itu.

Saya pengguna jQuery baru, beralih dari DOMAssistant, yang memiliki fungsi serupa: http://www.domassistant.com/documentation/DOMAssistantContent-module.php

Plugin saya lebih sederhana, saya pikir attrs dan konten lebih baik untuk ditambahkan dengan metode chaining:

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

Juga, ini adalah contoh yang baik untuk jQuery-plugin sederhana (yang ke-100).

ern0
sumber
4

Semuanya lurus ke depan! Berikut beberapa contoh cepat ...


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 );
Randy
sumber
1

Tidak disebutkan dalam jawaban sebelumnya, jadi saya menambahkan contoh kerja bagaimana membuat elemen elemen dengan jQuery terbaru, juga dengan atribut tambahan seperti konten, kelas, atau panggilan balik klik:

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>

Vladislav Ladicky
sumber
-2

jQuery di luar kotak tidak memiliki yang setara dengan createElement. Bahkan sebagian besar pekerjaan jQuery dilakukan secara internal menggunakan innerHTML alih-alih manipulasi DOM murni. Seperti yang disebutkan Adam di atas, ini adalah bagaimana Anda dapat mencapai hasil yang serupa.

Ada juga plugin yang tersedia yang menggunakan DOM lebih dari innerHTML seperti appendDOM , DOMEC dan FlyDOM hanya untuk beberapa nama. Dari segi kinerja, jquery asli masih merupakan yang paling berkinerja (terutama karena menggunakan innerHTML)

James Hughes
sumber
5
Anda harus mendapatkan informasi terbaru. jQuery tidak menggunakan innerHtml tetapi mem-parsing string HTML dan secara internal membangun pohon DOM menggunakan document.createElement (). Ini adalah jQuery inti.
Vincent Robert