Чи є найкраща практика для створення html за допомогою JavaScript


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.

Шаблонування не все так незріло, і ви бачите, що воно з’являється у більшості основних фреймворків Javascript.

Ось приклад модуля JQuery Template Plugin, який допоможе вам врятувати продуктивність, і це справді дуже просто:

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

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

Я кажу, пройдіться крутим маршрутом (і краще, більш ремонтованим) і використовуйте шаблони.


13
Здається, що шаблони JQuery мертві, дивіться stackoverflow.com/questions/7911732/…
Джеймс Макмахон

4
@Jim Fiorato: посилання мертва: s
Adrien Be

2
Як зазначає Адрієн, посилання мертва. Пропонуємо оновити свою відповідь, щоб включити: Mustache.js
Mr. Polywhirl

1
Може хто-небудь пояснить, чому відповідь на основі jQuery є прийнятою? Сумніваюся, що це найкраща практика!
WoIIe

1
@WoIIe Ще гірше, що плагін jQuery мертвий, тому ця відповідь застаріла.
Франклін Ю

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 є більш ефективною (припускаючи, що конкатенація рядків не є справжньою проблемою) та читабельна.
Родрік Чапман

Зв'язок рядків IE завжди є проблемою. Замість цього використовуйте масив.
десь

7

Можливо, більш сучасним підходом є використання такої мови шаблонів, як Mustache , яка має реалізацію на багатьох мовах, включаючи JavaScript. Наприклад:

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

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

Ви навіть отримуєте додаткову перевагу - ви можете повторно використовувати ті самі шаблони в інших місцях, наприклад, на стороні сервера.

Якщо вам потрібні складніші шаблони (якщо заяви, цикли тощо), ви можете використовувати руль, які мають більше функцій, і сумісні з вусами.


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
Акуратний. Я міг би використати щось подібне у великому проекті кілька місяців тому.
Родрік Чапман

Так. Лаконічні та акуратні!
ajitweb

4

Ви можете додати HTML-шаблон шаблону на свою сторінку в прихованому розділі, а потім використати 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.

Існує бібліотека javascript, яка значно спрощує цей процес під назвою 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. Це на тодолісті. Наразі ви можете просто використовувати вихід разом із звичайним 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 в цілому.

Зауважте, що за цим підходом існує парадигма: сервер виводить лише дані та (у разі взаємодії) отримує дані від клієнта асинхронулі з запитами AJAX. Код клієнта працює як окремий веб-додаток JavaScript.

Веб-додаток може працювати, візуалізувати інтерфейс, навіть не використовуючи сервер (звичайно, він не відображатиме жодних даних і не пропонує взаємодії).

Ця парадигма часто приймається останнім часом, і цілі рамки будуються навколо такого підходу (див., Наприклад, backbone.js).

2) З міркувань продуктивності, коли це можливо, краще побудувати html в рядку, а потім ввести його як ціле на сторінку.

3) Це ще один варіант, а також прийняття рамок веб-додатків. Інші користувачі розмістили різні доступні шаблонні двигуни. У мене складається враження, що ви маєте навички їх оцінювати та вирішувати, чи слід йти цим шляхом чи ні.

4) Ще один варіант. Але подайте його як звичайний текст / html; чому JSON? Мені не подобається такий підхід, тому що змішується PHP (мова вашого сервера) з Html. Але я приймаю це часто як розумний компроміс між варіантом 1 і 4 .


Моя відповідь: ви вже дивитесь у правильному напрямку.

Я пропоную прийняти підхід між 1 і 4, як я. В іншому випадку прийняти веб-рамку або механізм шаблонування.

Просто моя думка на основі мого досвіду ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.