jQuery document.createElement eşdeğeri?


1251

Bazı eski JavaScript kodlarını yeniden düzenliyorum ve devam eden DOM manipülasyonu var.

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

JQuery kullanarak bunu yapmak için daha iyi bir yolu olup olmadığını bilmek istiyorum. Şunu deniyorum:

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

Ama bunun daha iyi olup olmadığından emin değilim.


jsben.ch/#/ARUtz - jquery vs createElement için bir kriter
EscapeNetscape


Yakalanmayan TypeError: $ .create bir işlev değil
Tyguy7

Yanıtlar:


1290

"Bir" satırındaki örnek.

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

Güncelleme : Hala biraz trafik aldığı için bu yayını güncelleyeceğimi düşündüm. Aşağıdaki yorumlarda yeni öğeler yaratmanın bir yolu olarak $("<div>")vs $("<div></div>")vs ile ilgili bir tartışma var $(document.createElement('div'))ve hangisi "en iyi".

Küçük bir karşılaştırma yaptım ve işte yukarıdaki seçenekleri 100.000 kez tekrarlamanın sonuçları:

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

Bence bu büyük bir sürpriz değil, ama document.createElementen hızlı yöntem. Elbette, gitmeden ve tüm kod tabanınızı yeniden düzenlemeye başlamadan önce, burada bahsettiğimiz farklılıkların (jQuery'nin arkaik sürümleri hariç) bin öğe başına yaklaşık 3 milisaniyeye eşit olduğunu unutmayın .


Güncelleme 2

JQuery 1.7.2 için güncellendi ve JSBen.chmuhtemelen ilkel ölçütlerimden biraz daha bilimsel olan ölçütü koydu , ayrıca şimdi crowdsourced olabilir!

http://jsben.ch/#/ARUtz


70
Document.createElement öğesinin, jQuery'nin html dizenizi bir öğeye dönüştürmesinden çok daha hızlı olduğunu göreceksiniz. (işleri daha verimli hale getirme isteğiniz varsa)
Sugendran

25
Bu jQuery <1.3 için doğrudur Şimdi hız eşdeğer.
Rob Stevenson-Leggett

15
@Kevin, bu doğrudur, ancak jQuery daha fazla iş yapar (kapanış etiketi eklemek için bir regex ile çalışır), bu yüzden yukarıdaki yöntemi tercih ederim. Ayrıca, kodunuzu $('div')görsel olarak çok benzer olan, ancak işlevsel olarak kutuplayan farklılaştırır .
nickf

14
Temelde @Sungendran & @nickf'in bir kombinasyonu olurdu $(document.createElement('div'))ve en hızlısı olmalı?
Kolky

14
"Doğru" yolun $ ('<div />') olduğunu düşünüyorum, IMO ile daha da fazla "anlamı" var, çünkü bir Düğüm oluşturduğunuz oldukça açık. Kötü şey bu şekilde tüm editörlerde sözdizimi vurgulama kırıyor = (
Erik Escobedo

139

Sadece bir jQuery yapıcısına eklemek istediğiniz öğelerin HTML'sini sağlamak, $()jQuery'nin append()yöntemini kullanarak DOM'a eklenmeye uygun yeni inşa edilmiş HTML'den bir jQuery nesnesi döndürür .

Örneğin:

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

İsterseniz bu tabloyu programlı olarak doldurabilirsiniz.

Bu size kullanmaktan daha özlü bulabilir sınıf adları veya diğer özellikleri de dahil olmak üzere istediğiniz herhangi rastgele HTML, belirleme yeteneği sağlar createElementve daha sonra benzeri özelliklerini ayarlayarak cellSpacingve classNameJS yoluyla.


7
Belki bu açıktı ve örneğinizle belirtildi, ancak $ ("<html string>") sözdizimini kullanarak bir jQuery DOM öğesi oluşturmak, yerel <element> .appendChild yöntemi veya benzeri kullanılarak DOM'a eklenemez. JQuery append yöntemini kullanmalısınız.
Adam

4
$(htmlStr)olarak uygulanır document.createElement("div").innerHTML = htmlStr. Başka bir deyişle, tarayıcının HTML ayrıştırıcısını çağırır. Hatalı biçimlendirilmiş HTML, IE'de diğer tarayıcılara göre farklı şekilde kesiliyor.
Matthew

2
@Adam jQuery nesnesi get, yerel DOM öğesini döndüren işleve sahiptir. (Bu konunun eski olduğunu biliyorum, ancak referans olarak ekliyorum. ;-))
Constantino Tsarouhas,

1
Html dizesiyle ilgili sorunlar yaşıyorsanız jQuery.parseHTML
fguillen

1
@Adam Veya, kod akışınızda / gözlerinizde daha [dom element].appendChild($('<html>')[0]);
kolaysa


49

Ben böyle yapıyorum:

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

44

beri jQuery1.8kullanarak,$.parseHTML() elemanlar oluşturmak için daha iyi bir seçimdir.

iki faydası vardır:

1. gibi eski bir yöntem kullanırsanız $(string), jQuery bir html etiketi seçmek veya yeni bir öğe oluşturmak istediğinizden emin olmak için dizeyi inceler. Kullanarak $.parseHTML(), jQuery'ye açıkça yeni bir öğe oluşturmak istediğinizi söylersiniz, böylece performans biraz daha iyi olabilir.

2. daha önemli bir şey, eski yolu kullanırsanız siteler arası saldırı ( daha fazla bilgi ) muzdarip olabilir . şuna benzer bir şey varsa:

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

kötü bir adam <script src="xss-attach.js"></script>seni kızdırmak için giriş yapabilir . Neyse ki, $.parseHTML()bu utançtan kaçının:

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

Ancak, bir hQml öğesi aiken jQuery nesnesi olduğunu lütfen unutmayın b:

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

"Herhangi bir [öğe] öğesi" oluşturmak için "daha iyi seçim" güçlü olabilir. @ siergiej'in cevabı , parseHTMLharici kaynaklardan gelen html için iyi olduğunu söyleyerek iyi bir iş çıkarıyor , ancak " sonuçları yeni bir jQuery nesnesine sardıktan sonra tüm artış gitti ". Yani, yeni bir jQuery ile sarılmış html öğesinin oluşturulmasını zor kodlamak istiyorsanız, $("<div>stuff</div>")stil hala kazanıyor gibi görünüyor.
Ruffin

38

GÜNCELLEME

JQuery'nin en son sürümlerinden itibaren, aşağıdaki yöntem ikinci Nesnede geçirilen özellikleri atamaz

Önceki cevap

document.createElement('div')Birlikte kullanmak jQuerydaha hızlı hissediyorum :

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

29

Bu çok eski bir soru olmasına rağmen, bunu son bilgilerle güncellemenin iyi olacağını düşündüm;

JQuery 1.8'den beri , şimdi öğe oluşturmanın tercih edilen bir yolu olan bir jQuery.parseHTML () işlevi vardır. Ayrıca, $('(html code goes here)')resmi jQuery web sitesi üzerinden HTML ayrıştırma ile ilgili bazı sorunlar vardır, bunların yayın notlarından birinde aşağıdakilerden bahseder :

Rahat HTML ayrıştırma: $ (htmlString) etiketlerinden önce bir kez daha önde gelen boşluklara veya yeni satırlara sahip olabilirsiniz. Harici kaynaklardan elde edilen HTML'yi ayrıştırırken $ .parseHTML () yöntemini kullanmanızı ve gelecekte HTML ayrıştırma işleminde daha fazla değişiklik yapmayı öneriyoruz.

Asıl soru ile ilgili olarak, sağlanan örnek şuraya çevrilebilir:

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

maalesef sadece kullanmaktan daha az uygun $(), ancak size daha fazla kontrol sağlar, örneğin komut dosyası etiketlerini hariç tutmayı seçebilirsiniz (satır içi komut dosyalarını onclickolsa gibi bırakacaktır ):

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

Ayrıca, en iyi cevaptan yeni gerçekliğe ayarlanmış bir kıyaslama:

JSbin Bağlantısı

jQuery 1.9.1

  $ .parseHTML: 88 ms
  $ ($. ayrıştırmaMLML): 240ms
  <div> </div>: 138ms
  <div>: 143 ms
  createElement: 64 ms

Görünüşe parseHTMLçok daha yakın olduğunu createElementdaha $(), ancak tüm artırmak, yeni bir jQuery nesnesi sonuçlarını tamamlamasından sonra gitti



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

JQuery'de bir DIV öğesi oluşturmanın en kısa / en kolay yoludur.


5

Bunun için küçük bir jQuery eklentisi yaptım: https://github.com/ern0/jquery.create

Sözdiziminizi takip eder:

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

DOM düğümü kimliği ikinci parametre olarak belirtilebilir:

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

Ciddi mi? Hayır. Ancak bu sözdizimi $ ("<div> </div>") değerinden daha iyidir ve bu para için çok iyi bir değerdir.

Benzer bir işlevi olan DOMAssistant'tan geçiş yapan yeni bir jQuery kullanıcısıyım: http://www.domassistant.com/documentation/DOMAssistantContent-module.php

Benim eklenti daha basit, bence attrs ve içerik zincirleme yöntemleri ile eklemek daha iyidir:

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

Ayrıca, basit bir jQuery eklentisi (100.) için iyi bir örnek.


4

Her şey oldukça basit! Heres birkaç hızlı örnek ...


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

Önceki yanıtlarda belirtilmedi, bu yüzden en son jQuery ile öğe, içerik, sınıf veya onclick geri arama gibi ek özniteliklere sahip öğe öğelerinin nasıl oluşturulacağına dair çalışma örneği ekliyorum:

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

Kutudan çıkan jQuery, bir createElement öğesine eşdeğer değildir. Aslında jQuery'nin çalışmalarının çoğu, saf DOM manipülasyonu üzerinde innerHTML kullanılarak dahili olarak yapılır. Adam'ın yukarıda belirttiği gibi, benzer sonuçları nasıl elde edebileceğiniz budur.

Ayrıca böyle innerHTML üzerinde DOM kullanırlar o eklentileri vardır appendDOM , DOMEC ve FlyDOM sadece birkaç isim. Yerli jquery hala en performanslı performans (esas olarak innerHTML kullandığından)


5
Güncel olmalısın. jQuery innerHtml kullanmaz, ancak HTML dizesini ayrıştırır ve document.createElement () kullanarak dahili olarak bir DOM ağacı oluşturur. Bu çekirdek jQuery.
Vincent Robert
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.