Есть ли лучшая практика для генерации html с javascript?
Я звоню в веб-сервис, который возвращает массив объектов в формате JSON. Я хочу взять эти объекты и заполнить div с HTML. Допустим, каждый объект содержит URL-адрес и имя.
Если бы я хотел сгенерировать следующий HTML для каждого объекта:
<div><img src="the url" />the name</div>
Есть ли лучшая практика для этого? Я вижу несколько способов сделать это:
- Конкатенация строк
- Создать элементы
- Используйте шаблонный плагин
- Создайте HTML на сервере, а затем подайте через JSON.
Ответы
Ответ 1
Варианты # 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
});
Я говорю, отправляйся крутым маршрутом (и лучше выполняй, более обслуживаемым) и используйте шаблоны.
Ответ 2
Если вам абсолютно необходимо конкатенировать строки, а не обычные:
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 было очень быстро.
Ответ 3
Один из первых двух вариантов является общим и приемлемым.
Я приведу примеры каждого из 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
Ответ 4
Вот пример, используя мой Простые шаблоны плагин для jQuery:
var tmpl = '<div class="#{classname}">#{content}</div>';
var vals = {
classname : 'my-class',
content : 'This is my content.'
};
var html = $.tmpl(tmpl, vals);
Ответ 5
Возможно, более современный подход заключается в использовании языка шаблонов, такого как Mustache, который имеет реализации на многих языках, включая javascript. Например:
var view = {
url: "/hello",
name: function () {
return 'Jo' + 'hn';
}
};
var output = Mustache.render('<div><img src="{{url}}" />{{name}}</div>', view);
Вы даже получаете дополнительное преимущество - вы можете повторно использовать те же шаблоны в других местах, например на стороне сервера.
Если вам нужны более сложные шаблоны (если инструкции, циклы и т.д.), вы можете использовать Handlebars, который имеет больше возможностей и совместим с Усы.
Ответ 6
Вы можете добавить 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*/})
Ответ 7
Раскрытие информации: Я являюсь сторонником 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
.
Ответ 8
Есть ли наилучшая практика для этого? Я вижу несколько способов сделать это:
- Строки конкатенации
- Создание элементов
- Используйте плагин templating
- Создайте html на сервере, а затем выполните через JSON.
1) Это вариант. Создайте html с JavaScript на стороне клиента, а затем введите его в DOM в целом.
Обратите внимание, что для этого подхода существует парадигма: сервер выводит только данные и (в случае взаимодействия) получает данные от клиента asyncronoulsy с запросами AJAX. Клиентский код работает как автономное веб-приложение JavaScript.
Веб-приложение может работать, отображать интерфейс, даже если сервер не работает (конечно, он не будет отображать какие-либо данные или предлагать какое-либо взаимодействие).
Эта парадигма часто принимается в последнее время, и вокруг этого подхода строятся целые структуры (например, backbone.js).
2) По соображениям производительности, когда это возможно, лучше построить html в строке, а затем вставить его в целом на страницу.
3) Это еще один вариант, а также принятие рамок веб-приложений. Другие пользователи размещают различные доступные шаблоны. У меня сложилось впечатление, что у вас есть навыки, чтобы оценить их и решить, следует ли следовать этому пути или нет.
4) Другой вариант. Но подавайте его как обычный текст /html; почему JSON? Мне не нравится этот подход, потому что смешивает PHP (ваш серверный язык) с Html. Но я часто принимаю его как разумный компромисс между опцией 1 и 4.
Мой ответ: вы уже смотрите в правильном направлении.
Я предлагаю использовать подход между 1 и 4, как я. В противном случае используйте веб-фреймворк или механизм шаблонов.
Просто мое мнение основано на моем опыте...