jQuery document.createElement ที่เทียบเท่ากัน?


1251

ฉันกำลังสร้างโค้ด JavaScript เก่าอีกครั้งและมีการจัดการ DOM เกิดขึ้นมากมาย

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 ฉันกำลังทดลองกับ:

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

แต่ฉันไม่แน่ใจว่าจะดีกว่านี้หรือไม่


jsben.ch/#/ARUtz - มาตรฐานสำหรับ jquery vs createElement
EscapeNetscape

ซ้ำซ้อนที่เป็นไปได้ของการสร้างองค์ประกอบ div ใน jQuery
T.Todua

Uncaught TypeError: $ .create ไม่ใช่ฟังก์ชั่น
Tyguy7

คำตอบ:


1290

นี่คือตัวอย่างของคุณในบรรทัด "หนึ่ง"

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

อัปเดต : ฉันคิดว่าฉันจะอัปเดตโพสต์นี้เนื่องจากยังมีการรับส่งข้อมูลค่อนข้างน้อย ในความคิดเห็นด้านล่างมีการอภิปรายเกี่ยวกับ$("<div>")vs $("<div></div>")vs $(document.createElement('div'))เป็นวิธีในการสร้างองค์ประกอบใหม่ซึ่งเป็น "ดีที่สุด"

ฉันรวบรวมเกณฑ์มาตรฐานขนาดเล็กและนี่คือผลลัพธ์ของการทำซ้ำตัวเลือกข้างต้นโดยประมาณ 100,000 ครั้ง:

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

ฉันคิดว่ามันไม่น่าแปลกใจ แต่document.createElementเป็นวิธีที่เร็วที่สุด แน่นอนว่าก่อนที่คุณจะออกไปและเริ่มต้น refactoring codebase ทั้งหมดของคุณจำไว้ว่าความแตกต่างที่เรากำลังพูดถึงที่นี่ (ในทุก แต่รุ่นเก่าของ jQuery) ถือเอาการเกี่ยวกับการพิเศษ 3 มิลลิวินาทีต่อพันองค์ประกอบ


อัปเดต 2

อัปเดตสำหรับjQuery 1.7.2และวางมาตรฐานJSBen.chซึ่งอาจเป็นเรื่องทางวิทยาศาสตร์มากกว่าการวัดแบบดั้งเดิมของฉันเล็กน้อยบวกกับตอนนี้ผู้คนสามารถมาเยี่ยมชมได้ที่นี่!

http://jsben.ch/#/ARUtz


70
คุณจะพบว่า document.createElement นั้นเร็วกว่าการให้ jQuery แปลงสตริง html ของคุณเป็นองค์ประกอบ (ในกรณีที่คุณมีการกระตุ้นที่จะทำให้สิ่งที่มีประสิทธิภาพมากขึ้น)
Sugendran

25
นั่นเป็นเรื่องจริงสำหรับ jQuery <1.3 มันเทียบเท่าความเร็วแล้วตอนนี้ที่ฉันเชื่อ
Rob Stevenson-Leggett

15
@ เควินนั่นเป็นจริง แต่มันทำให้ jQuery ทำงานได้มากขึ้น (มันทำงานผ่าน regex เพื่อเพิ่มแท็กปิด) ดังนั้นฉันชอบวิธีการด้านบน นอกจากนี้ยังทำให้รหัสของคุณแตกต่างจาก$('div')ที่คล้ายกันมากกับสายตา
nickf

14
ดังนั้นโดยพื้นฐานแล้วการรวมกันของ @Sungendran & @nickf น่าจะเป็น$(document.createElement('div'))และมันควรจะเร็วที่สุด?
Kolky

14
ฉันคิดว่าวิธีที่ "ถูกต้อง" คือ $ ('<div />') พร้อมด้วย IMO มี "ความหมาย" มากยิ่งขึ้นเนื่องจากเห็นได้ชัดว่าคุณกำลังสร้างโหนด สิ่งที่ไม่ดีคือวิธีนี้แบ่งการเน้นไวยากรณ์ในโปรแกรมแก้ไขทั้งหมด = (
Erik Escobedo

139

เพียงส่ง HTML ขององค์ประกอบที่คุณต้องการเพิ่มไปยังตัวสร้าง jQuery $()จะส่งคืนวัตถุ jQuery จาก HTML ที่สร้างขึ้นใหม่ซึ่งเหมาะสำหรับการผนวกเข้ากับ DOM โดยใช้append()วิธีการของ jQuery

ตัวอย่างเช่น:

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

จากนั้นคุณสามารถเติมตารางนี้โดยทางโปรแกรมหากคุณต้องการ

สิ่งนี้ให้ความสามารถในการระบุ HTML ที่คุณต้องการรวมถึงชื่อคลาสหรือคุณลักษณะอื่น ๆ ซึ่งคุณอาจพบว่ากระชับกว่าการใช้createElementแล้วตั้งค่าคุณสมบัติเช่นcellSpacingและclassNameผ่าน JS


7
บางทีสิ่งนี้อาจเห็นได้ชัดและบ่งชี้โดยตัวอย่างของคุณ แต่การสร้างองค์ประกอบ jQuery DOM โดยใช้ไวยากรณ์ $ ("<html string>") ไม่สามารถผนวกเข้ากับ DOM โดยใช้เมธอด <element> .appendChild หรือสิ่งที่คล้ายกัน คุณต้องใช้วิธีต่อท้าย jQuery
Adam

4
$(htmlStr)document.createElement("div").innerHTML = htmlStrจะดำเนินการเป็น กล่าวอีกนัยหนึ่งมันจะเรียกใช้ตัวแยกวิเคราะห์ HTML ของเบราว์เซอร์ HTML ที่มีรูปแบบผิดปกติแตกต่างกันใน IE เทียบกับเบราว์เซอร์อื่น
แมทธิว

2
@Adam วัตถุ jQuery มีgetฟังก์ชั่นซึ่งจะส่งกลับองค์ประกอบ DOM พื้นเมือง (ฉันรู้ว่าหัวข้อนี้เก่า แต่ฉันเพิ่มเพื่อการอ้างอิง ;-))
Constantino Tsarouhas

1
หากคุณกำลังมีปัญหากับสตริง html ลองแยกวิเคราะห์มันด้วยjQuery.parseHTML
fguillen

1
@Adam หรือถ้ามันง่ายขึ้นในการไหลของรหัส / ดวงตาของคุณคุณสามารถทำได้[dom element].appendChild($('<html>')[0]);
ACK_stoverflow

67

การสร้างองค์ประกอบ DOM ใหม่เป็นคุณสมบัติหลักของjQuery()วิธีการโปรดดู:


17
ขอบคุณสำหรับการเชื่อมโยงเอกสาร! $('<a>')เป็นไปไม่ได้!
พันเอก Panic


44

เนื่องจากการjQuery1.8ใช้$.parseHTML()เพื่อสร้างองค์ประกอบเป็นตัวเลือกที่ดีกว่า

มีสองประโยชน์:

1. ถ้าคุณใช้วิธีเก่า ๆ ซึ่งอาจเป็นสิ่งที่ชอบ $(string) jQuery จะตรวจสอบสตริงเพื่อให้แน่ใจว่าคุณต้องการเลือกแท็ก html หรือสร้างองค์ประกอบใหม่ โดยการใช้$.parseHTML()คุณบอก jQuery ว่าคุณต้องการสร้างองค์ประกอบใหม่อย่างชัดเจนดังนั้นประสิทธิภาพอาจดีขึ้นเล็กน้อย

2. สิ่งที่สำคัญกว่านั้นคือคุณอาจประสบกับการโจมตีจากเว็บไซต์ ( ข้อมูลเพิ่มเติม ) ถ้าคุณใช้วิธีการแบบเก่า หากคุณมีสิ่งที่ชอบ:

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

คนเลวสามารถป้อนข้อมูล<script src="xss-attach.js"></script>เพื่อแซวคุณ โชคดีที่$.parseHTML()หลีกเลี่ยงความอับอายนี้สำหรับคุณ:

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

อย่างไรก็ตามโปรดสังเกตว่าaเป็นวัตถุ jQuery ในขณะที่bเป็นองค์ประกอบ html:

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

"ทางเลือกที่ดีกว่า" ถึง "สร้างองค์ประกอบใด ๆ " อาจมีความแข็งแกร่ง คำตอบของ @ siergiejทำงานได้ดีในการพูดว่าparseHTMLดีสำหรับ html ที่มาจากแหล่งภายนอก แต่นั่น " การเพิ่มทั้งหมดจะหายไปหลังจากห่อผลลัพธ์ในวัตถุ jQuery ใหม่ " นั่นคือถ้าคุณต้องการโค้ดอย่างหนักในการสร้างองค์ประกอบ html ที่ห่อด้วย jQuery ใหม่$("<div>stuff</div>")สไตล์ก็ยังคงชนะอยู่
ruffin

38

UPDATE

ตั้งแต่ jQuery รุ่นล่าสุดวิธีการต่อไปนี้ไม่ได้กำหนดคุณสมบัติที่ส่งผ่านในวัตถุที่สอง

คำตอบก่อนหน้า

ฉันรู้สึกว่าใช้document.createElement('div')ร่วมกับjQueryเร็วกว่า:

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

29

แม้ว่านี่จะเป็นคำถามที่เก่ามาก แต่ฉันคิดว่ามันคงจะดีถ้าได้อัพเดทกับข้อมูลล่าสุด

ตั้งแต่ jQuery 1.8 มีฟังก์ชั่นjQuery.parseHTML ()ซึ่งตอนนี้เป็นวิธีที่ต้องการในการสร้างองค์ประกอบ นอกจากนี้ยังมีปัญหาบางอย่างกับการแยกวิเคราะห์ HTML ผ่าน$('(html code goes here)')เช่นเว็บไซต์ทางการ jQuery กล่าวถึงสิ่งต่อไปนี้ในบันทึกย่อประจำรุ่นหนึ่งรายการ :

การแยกวิเคราะห์ HTML ที่ผ่อนคลาย: คุณสามารถมีช่องว่างนำหน้าหรือขึ้นบรรทัดใหม่อีกครั้งก่อนแท็กใน $ (htmlString) เรายังคงแนะนำอย่างยิ่งให้คุณใช้ $ .parseHTML () เมื่อแยกวิเคราะห์ HTML ที่ได้รับจากแหล่งภายนอกและอาจทำการเปลี่ยนแปลงเพิ่มเติมในการแยกวิเคราะห์ HTML ในอนาคต

หากต้องการเกี่ยวข้องกับคำถามจริงสามารถแปลตัวอย่างที่ให้เป็น:

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

ซึ่งน่าเสียดายที่ไม่สะดวกกว่าการใช้งานเพียงอย่างเดียว$()แต่ช่วยให้คุณควบคุมได้มากขึ้นตัวอย่างเช่นคุณอาจเลือกที่จะยกเว้นแท็กสคริปต์ (ซึ่งจะทำให้สคริปต์แบบอินไลน์เหมือนonclick):

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

นอกจากนี้นี่คือมาตรฐานจากคำตอบที่ได้รับการปรับให้เข้ากับความเป็นจริงใหม่:

ลิงก์ JSbin

jQuery 1.9.1

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

ดูเหมือนว่าparseHTMLจะเข้าใกล้createElementมากกว่า$()แต่การเพิ่มทั้งหมดจะหายไปหลังจากห่อผลลัพธ์ในวัตถุ jQuery ใหม่



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

เป็นวิธีที่สั้น / ง่ายที่สุดในการสร้างองค์ประกอบ DIV ใน jQuery


5

ฉันเพิ่งสร้างปลั๊กอิน jQuery ขนาดเล็กเพื่อที่: https://github.com/ern0/jquery.create

มันเป็นไปตามไวยากรณ์ของคุณ:

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

ID โหนด DOM สามารถระบุได้เป็นพารามิเตอร์ตัวที่สอง:

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

จริงจังหรือไม่ ไม่ แต่ไวยากรณ์นี้ดีกว่า$ ("<div> </div>")และมันคุ้มค่ามากสำหรับเงินนั้น

ฉันเป็นผู้ใช้ jQuery ใหม่เปลี่ยนจาก DOMAssistant ซึ่งมีฟังก์ชั่นที่คล้ายกัน: http://www.domassistant.com/documentation/DOMAssistantContent-module.php

ปลั๊กอินของฉันง่ายขึ้นฉันคิดว่าผู้ดูแลและเนื้อหาควรเพิ่มโดยวิธีการผูกมัด:

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

นอกจากนี้ยังเป็นตัวอย่างที่ดีสำหรับ jQuery-plugin อย่างง่าย (อันที่ 100)


4

มันตรงไปตรงมาทั้งหมด! นี่คือตัวอย่างรวดเร็วสองสาม ...


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

ไม่ได้กล่าวถึงในคำตอบก่อนหน้าดังนั้นฉันจึงเพิ่มตัวอย่างการทำงานวิธีสร้างองค์ประกอบองค์ประกอบด้วย jQuery ล่าสุดรวมถึงแอตทริบิวต์เพิ่มเติมเช่นเนื้อหาคลาสหรือการเรียกกลับ 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 จากกล่องไม่มีค่าเท่ากับ createElement ในความเป็นจริงแล้วงานส่วนใหญ่ของ jQuery นั้นทำโดยใช้ InnerHTML ในการจัดการ DOM อย่างแท้จริง ดังที่อดัมได้กล่าวถึงข้างต้นนี่คือวิธีที่คุณสามารถบรรลุผลลัพธ์ที่คล้ายกัน

นอกจากนี้ยังมีปลั๊กอินที่ใช้งาน DOM ผ่านInnerHTMLเช่นappendDOM , DOMECและFlyDOMเพื่อตั้งชื่อให้ไม่กี่อัน ประสิทธิภาพการทำงานฉลาด jQuery ดั้งเดิมยังคงเป็นนักแสดงมากที่สุด (ส่วนใหญ่เนื่องจากมันใช้ InnerHTML)


5
คุณควรได้รับการปรับปรุง jQuery ไม่ได้ใช้ innerHtml แต่แยกวิเคราะห์สตริง HTML และสร้างแผนผัง DOM ภายในโดยใช้ document.createElement () นี่คือ jQuery หลัก
Vincent Robert
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.