Есть ли лучшая практика для создания 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
Выбор от 1 до 4: зависит от того, сколько контента должно быть введено (лучше 4 для большего), сколько разных частей html нужно будет добавить всего (3 или 4). с чем sb знаком. (Влияние на время разработки). Если вы не знаете каких-либо инструментов, это всего лишь небольшой модальный файл, который будет внедрен, как только я не знаю, как это сделать лучше, чем чистый js (1-2)
partizanos

Ответы:

68

Варианты №1 и №2 будут вашими самыми непосредственными и простыми вариантами, однако для обоих вариантов вы почувствуете влияние на производительность и обслуживание, создавая строки или создавая объекты DOM.

Шаблоны не так уж и незрелы, и вы видите их всплывающими в большинстве основных фреймворков Javascript.

Вот пример плагина шаблонов JQuery , который сэкономит вам падение производительности и действительно очень прост:

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
Мистер Поливирл
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 раз, а выделение памяти может быть медленным. После двух итераций у вас есть «testingtesting». После трех итераций эта строка отбрасывается, и выделяется память, в которой достаточно места для «тестирования, тестирования, тестирования». И так 200 раз, постепенно увеличивая длину. Однако s.join () выделяет одну новую строку в результате, достаточно длинную, чтобы вместить их все, а затем копирует каждую из них. Одно выделение, намного быстрее.
EricP
1
@JoeCoder, согласен, это алгоритм Shlemiel The Painter. joelonsoftware.com/articles/fog0000000319.html
Джодрелл,
8

Любой из первых двух вариантов является обычным и приемлемым.

Я приведу примеры каждого из них в Prototype .

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

Вы даже получаете дополнительное преимущество - вы можете повторно использовать те же шаблоны в других местах, например, на стороне сервера.

Если вам нужны более сложные шаблоны (операторы if, циклы и т. Д.), Вы можете использовать Handlebars, которые имеют больше функций и совместимы с Mustache.

Цах
источник
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 02
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.

Существует библиотека 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. Это в 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 доступен на Bower , поэтому вы можете получить его, запустив bower install BOB.

Automatico
источник
2

Есть ли лучший способ для этого? Я вижу несколько способов сделать это:

  1. Объединить строки
  2. Создать элементы
  3. Используйте плагин для шаблонов
  4. Создайте HTML-код на сервере, а затем обработайте его через JSON.

1) Это вариант. Создайте html с помощью JavaScript на стороне клиента, а затем вставьте его в DOM в целом.

Обратите внимание, что за этим подходом стоит парадигма: сервер выводит только данные и (в случае взаимодействия) получает данные от клиента asyncronoulsy с запросами AJAX. Код на стороне клиента работает как отдельное веб-приложение на JavaScript.

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

В последнее время эта парадигма часто принимается, и на ее основе строятся целые фреймворки (см., Например, backbone.js).

2) По соображениям производительности, когда это возможно, лучше построить html в строке, а затем ввести его целиком на страницу.

3) Это еще один вариант, а также внедрение инфраструктуры веб-приложений. Другие пользователи разместили различные доступные механизмы шаблонов. У меня сложилось впечатление, что у вас есть навыки, чтобы оценить их и решить, идти по этому пути или нет.

4) Другой вариант. Но подавайте его как обычный текст / html; почему JSON? Мне не нравится этот подход, потому что PHP (язык вашего сервера) смешивается с Html. Но я часто принимаю это как разумный компромисс между вариантами 1 и 4 .


Мой ответ: вы уже смотрите в правильном направлении.

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

Просто мое мнение, основанное на моем опыте ...

Паоло
источник