มีแนวทางปฏิบัติที่ดีที่สุดในการสร้าง html ด้วยจาวาสคริปต์หรือไม่


103

ฉันกำลังเรียกใช้บริการเว็บที่ส่งคืนอาร์เรย์ของวัตถุใน JSON ฉันต้องการรับวัตถุเหล่านั้นและเติม div ด้วย HTML สมมติว่าแต่ละออบเจ็กต์มี url และชื่อ

หากฉันต้องการสร้าง HTML ต่อไปนี้สำหรับแต่ละออบเจ็กต์:

<div><img src="the url" />the name</div>

มีแนวทางปฏิบัติที่ดีที่สุดสำหรับสิ่งนี้หรือไม่? ฉันสามารถดูวิธีการทำได้สองสามวิธี:

  1. เชื่อมต่อสตริง
  2. สร้างองค์ประกอบ
  3. ใช้ปลั๊กอินเทมเพลต
  4. สร้าง html บนเซิร์ฟเวอร์จากนั้นให้บริการผ่าน JSON

1
คุณสามารถตรวจสอบขีดล่าง js: documentcloud.github.com/underscore/#templateมันเล่นได้ดีมากกับ backbone.js
luacassus

ตัวเลือก mong 1-4: ขึ้นอยู่กับปริมาณเนื้อหาที่จะฉีด (ชอบ 4 มากกว่า) จำนวนส่วน html ที่แตกต่างกันจะต้องต่อท้ายทั้งหมด (3 หรือ 4) สิ่งที่ sb คุ้นเคย (มีอิทธิพลต่อเวลาในการพัฒนา) ถ้าคุณไม่รู้จักเครื่องมือใด ๆ มันเป็นเพียงกิริยาเล็ก ๆ ที่จะฉีดเมื่อฉันไม่รู้วิธีที่ดีกว่า js บริสุทธิ์ที่จะทำ (1-2)
partizanos

คำตอบ:


68

ตัวเลือก # 1 และ # 2 จะเป็นตัวเลือกที่ตรงไปตรงมาที่สุดของคุณอย่างไรก็ตามสำหรับทั้งสองตัวเลือกคุณจะรู้สึกถึงผลกระทบด้านประสิทธิภาพและการบำรุงรักษาโดยการสร้างสตริงหรือการสร้างวัตถุ DOM

Templating ไม่ใช่ทั้งหมดที่ยังไม่บรรลุนิติภาวะและคุณจะเห็นป๊อปอัปในเฟรมเวิร์ก Javascript ส่วนใหญ่

นี่คือตัวอย่างในJQuery Template Pluginที่จะช่วยให้คุณประหยัดประสิทธิภาพได้และตรงไปตรงมามาก:

var t = $.template('<div><img src="${url}" />${name}</div>');

$(selector).append( t , {
     url: jsonObj.url,
     name: jsonObj.name
});

ฉันว่าไปเส้นทางที่เจ๋ง (และมีประสิทธิภาพดีกว่าบำรุงรักษาได้มากกว่า) และใช้เทมเพลต


13
JQuery templating ดูเหมือนจะตายไปแล้วดูstackoverflow.com/questions/7911732/…
James McMahon

4
@ Jim Fiorato: ลิงค์ตายแล้ว: s
Adrien Be

2
ลิงค์ตายแล้วขณะที่เอเดรียนชี้ให้เห็น ขอแนะนำให้คุณอัปเดตคำตอบของคุณ ได้แก่Moustache.js
Mr.Polywhirl

1
ใครช่วยอธิบายได้ไหมว่าทำไมคำตอบที่ใช้ jQuery จึงเป็นคำตอบที่ได้รับการยอมรับ ฉันสงสัยว่านี่เป็นแนวทางปฏิบัติที่ดีที่สุด!
WoIIe

1
@WoIIe ที่แย่กว่านั้นคือปลั๊กอิน jQuery นั้นตายไปแล้วดังนั้นคำตอบนี้จึงล้าสมัย
Franklin Yu

13

หากคุณต้องต่อสตริงเข้าด้วยกันแทนที่จะเป็นแบบปกติ:

var s="";
for (var i=0; i < 200; ++i) {s += "testing"; }

ใช้อาร์เรย์ชั่วคราว:

var s=[];
for (var i=0; i < 200; ++i) { s.push("testing"); }
s = s.join("");

การใช้อาร์เรย์นั้นเร็วกว่ามากโดยเฉพาะใน IE ฉันได้ทำการทดสอบกับสตริงเมื่อไม่นานมานี้กับ IE7, Opera และ FF Opera ใช้เวลาเพียง 0.4 วินาทีในการทดสอบ แต่ IE7 ยังไม่เสร็จหลังจาก 20 นาที !!!! (ไม่ฉันไม่ได้ล้อเล่น) ด้วยอาร์เรย์ IE นั้นเร็วมาก


ฉันเปลี่ยนเบราว์เซอร์มานานแล้วดังนั้นฉันจึงไม่ต้องทนทุกข์ทรมานมากขนาดนั้น IE เป็นเบราว์เซอร์ที่น่ากลัว แต่มันก็ดีขึ้นเรื่อย ๆ แต่สงสัยจะเปลี่ยนกลับไปแล้ว
บาง

1
ประสิทธิภาพการทำงานช้าที่เห็นในวิธีแรกน่าจะเป็นเพราะสตริงผลลัพธ์ต้องถูกจัดสรรใหม่ 200 ครั้งและการจัดสรรหน่วยความจำอาจช้า หลังจากทำซ้ำสองครั้งคุณมี "การทดสอบการทดสอบ" หลังจากทำซ้ำสามครั้งสตริงนั้นจะถูกทิ้งไปและหน่วยความจำที่มีพื้นที่เพียงพอสำหรับ "การทดสอบการทดสอบ" จะถูกจัดสรร ไปเรื่อย ๆ 200 เท่าโดยค่อยๆเพิ่มความยาว อย่างไรก็ตาม s.join () จะจัดสรรสตริงใหม่หนึ่งสตริงซึ่งเป็นผลลัพธ์ที่ยาวพอที่จะใส่ทั้งหมดได้จากนั้นคัดลอกในแต่ละสตริง การจัดสรรหนึ่งครั้งเร็วขึ้นมาก
EricP

1
@JoeCoder เห็นด้วยอัลกอริทึมของ Shlemiel The Painter joelonsoftware.com/articles/fog0000000319.html
Jodrell

8

ตัวเลือกสองตัวแรกทั้งสองตัวเลือกเป็นเรื่องธรรมดาและยอมรับ

ผมจะยกตัวอย่างของแต่ละคนในต้นแบบ

// assuming JSON looks like this:
// { 'src': 'foo/bar.jpg', 'name': 'Lorem ipsum' }

แนวทาง # 1:

var html = "<div><img src='#{src}' /> #{name}</div>".interpolate(json);
$('container').insert(html); // inserts at bottom

แนวทาง # 2:

var div = new Element('div');
div.insert( new Element('img', { src: json.src }) );
div.insert(" " + json.name);
$('container').insert(div); // inserts at bottom

การสร้าง HTML อย่างชัดเจนด้วยสตริงแทนที่จะเป็นองค์ประกอบ DOM นั้นมีประสิทธิภาพมากกว่า (สมมติว่าการต่อสตริงไม่ใช่ปัญหาจริง) และอ่านได้
Rodrick Chapman

ในการต่อสายอักขระ IE มักเป็นปัญหา ใช้อาร์เรย์แทน
บางที่

7

บางทีวิธีการที่ทันสมัยกว่านั้นคือการใช้ภาษาเทมเพลตเช่นMoustacheซึ่งมีการนำไปใช้งานในหลายภาษารวมถึงจาวาสคริปต์ ตัวอย่างเช่น:

var view = {
  url: "/hello",
  name: function () {
    return 'Jo' + 'hn';
  }
};

var output = Mustache.render('<div><img src="{{url}}" />{{name}}</div>', view);

คุณยังได้รับประโยชน์เพิ่มเติม - คุณสามารถใช้เทมเพลตเดียวกันนี้ซ้ำได้ในที่อื่น ๆ เช่นฝั่งเซิร์ฟเวอร์

หากคุณต้องการเทมเพลตที่ซับซ้อนมากขึ้น (หากเป็นคำสั่งลูป ฯลฯ ) คุณสามารถใช้Handlebarsซึ่งมีคุณสมบัติมากกว่าและเข้ากันได้กับ Moustache


6

นี่คือตัวอย่างการใช้ปลั๊กอินSimple Templatesสำหรับ jQuery:

var tmpl = '<div class="#{classname}">#{content}</div>';
var vals = {
    classname : 'my-class',
    content   : 'This is my content.'
};
var html = $.tmpl(tmpl, vals);

1
เรียบร้อย. ฉันสามารถใช้สิ่งที่ชอบในโปรเจ็กต์ใหญ่เมื่อสองสามเดือนก่อน
Rodrick Chapman

ใช่. กระชับและเรียบร้อย!
ajitweb

4

คุณสามารถเพิ่มเทมเพลต HTML ลงในเพจของคุณใน div ที่ซ่อนอยู่จากนั้นใช้ cloneNode และสิ่งอำนวยความสะดวกในการสืบค้นของไลบรารีที่คุณชื่นชอบเพื่อเติมข้อมูล

/* CSS */
.template {display:none;}

<!--HTML-->
<div class="template">
  <div class="container">
    <h1></h1>
    <img src="" alt="" />
  </div>
</div>

/*Javascript (using Prototype)*/
var copy = $$(".template .container")[0].cloneNode(true);
myElement.appendChild(copy);
$(copy).select("h1").each(function(e) {/*do stuff to h1*/})
$(copy).select("img").each(function(e) {/*do stuff to img*/})

3

การเปิดเผยข้อมูล: ฉันเป็นผู้ดูแล BOB

มีห้องสมุดจาวาสคริปต์ที่ทำให้กระบวนการนี้ง่ายขึ้นมากเรียกว่าบ๊อบ

สำหรับตัวอย่างเฉพาะของคุณ:

<div><img src="the url" />the name</div>

สิ่งนี้สามารถสร้างขึ้นด้วย BOB โดยใช้รหัสต่อไปนี้

new BOB("div").insert("img",{"src":"the url"}).up().content("the name").toString()
//=> "<div><img src="the url" />the name</div>"

หรือด้วยไวยากรณ์ที่สั้นกว่า

new BOB("div").i("img",{"src":"the url"}).up().co("the name").s()
//=> "<div><img src="the url" />the name</div>"

ไลบรารีนี้มีประสิทธิภาพมากและสามารถใช้เพื่อสร้างโครงสร้างที่ซับซ้อนมากด้วยการแทรกข้อมูล (คล้ายกับ d3) เช่น:

data = [1,2,3,4,5,6,7]
new BOB("div").i("ul#count").do(data).i("li.number").co(BOB.d).up().up().a("a",{"href": "www.google.com"}).s()
//=> "<div><ul id="count"><li class="number">1</li><li class="number">2</li><li class="number">3</li><li class="number">4</li><li class="number">5</li><li class="number">6</li><li class="number">7</li></ul></div><a href="www.google.com"></a>"

ขณะนี้ BOB ไม่สนับสนุนการแทรกข้อมูลลงใน DOM นี่คือ todolist ในตอนนี้คุณสามารถใช้เอาต์พุตร่วมกับ JS ปกติหรือ jQuery และวางไว้ที่ใดก็ได้ที่คุณต้องการ

document.getElementById("parent").innerHTML = new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s();
//Or jquery:
$("#parent").append(new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s());

ฉันสร้างห้องสมุดนี้เพราะฉันไม่พอใจกับทางเลือกอื่น ๆ เช่น jquery และ d3 รหัสซับซ้อนมากและอ่านยาก การทำงานกับ BOB อยู่ในความคิดของฉันซึ่งเห็นได้ชัดว่ามีความลำเอียงน่าพอใจกว่ามาก

BOB มีอยู่ในBowerดังนั้นคุณสามารถเรียกใช้งานbower install BOBได้


2

มีแนวทางปฏิบัติที่ดีที่สุดสำหรับสิ่งนี้หรือไม่? ฉันสามารถดูวิธีการทำได้สองสามวิธี:

  1. เชื่อมต่อสตริง
  2. สร้างองค์ประกอบ
  3. ใช้ปลั๊กอินเทมเพลต
  4. สร้าง html บนเซิร์ฟเวอร์จากนั้นให้บริการผ่าน JSON

1)นี่คือตัวเลือก สร้าง html ด้วย JavaScript ที่ฝั่งไคลเอ็นต์จากนั้นจึงฉีดเข้าไปใน DOM โดยรวม

โปรดทราบว่ามีกระบวนทัศน์ที่อยู่เบื้องหลังแนวทางนี้: เซิร์ฟเวอร์จะส่งออกข้อมูลเพียงอย่างเดียวและ (ในกรณีของการโต้ตอบ) รับข้อมูลจากไคลเอนต์ asyncronoulsy ด้วยการร้องขอ AJAX โค้ดฝั่งไคลเอ็นต์ใช้เป็นเว็บแอ็พพลิเคชัน JavaScript แบบสแตนด์อะโลน

เว็บแอปพลิเคชันอาจทำงานแสดงผลอินเทอร์เฟซแม้ว่าเซิร์ฟเวอร์จะไม่ทำงานก็ตาม (แน่นอนว่าจะไม่แสดงข้อมูลใด ๆ หรือเสนอการโต้ตอบใด ๆ )

กระบวนทัศน์นี้ได้รับการนำมาใช้บ่อยครั้งในช่วงไม่นานนี้และกรอบทั้งหมดถูกสร้างขึ้นจากแนวทางนี้ (ดูตัวอย่างเช่น backbone.js)

2)ด้วยเหตุผลด้านประสิทธิภาพหากเป็นไปได้ควรสร้าง html ในสตริงจากนั้นจึงฉีดโดยรวมลงในเพจ

3)นี่เป็นอีกทางเลือกหนึ่งเช่นเดียวกับการนำ Web Application framework มาใช้ ผู้ใช้รายอื่นได้โพสต์เครื่องมือสร้างเทมเพลตต่างๆ ฉันรู้สึกว่าคุณมีทักษะในการประเมินและตัดสินใจว่าจะเดินตามเส้นทางนี้หรือไม่

4)อีกทางเลือกหนึ่ง แต่แสดงเป็นข้อความธรรมดา / html; ทำไมต้องเป็น JSON ฉันไม่ชอบวิธีนี้เพราะผสม PHP (ภาษาเซิร์ฟเวอร์ของคุณ) กับ Html แต่ผมนำมาใช้ก็มักจะเป็นประนีประนอมที่เหมาะสมระหว่างตัวเลือกที่1และ4


คำตอบของฉัน: คุณกำลังมองไปในทิศทางที่ถูกต้องแล้ว

ฉันขอแนะนำให้ใช้แนวทางระหว่าง1ถึง4เหมือนที่ฉันทำ มิฉะนั้นให้ใช้เว็บเฟรมเวิร์กหรือเครื่องมือสร้างเทมเพลต

แค่ความคิดเห็นจากประสบการณ์ของฉัน ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.