JQuery - лучшая практика для создания сложных фрагментов HTML
Существует ли общая практика создания нескольких сложных элементов HTML в jQuery? Я пробовал несколько разных способов.
Сначала я попробовал использовать createElement и связать много из них вместе с AppendTo и т.п.:
var badge = $(document.createElement("div")).attr("class", "wrapper1").appendTo("body");
$(document.createElement("div")).attr("class", "wrapper2").appendTo(".wrapper1");
$(document.createElement("table")).attr("class", "badgeBody").appendTo(".wrapper2");
$(document.createElement("tr")).attr("class", "row1").appendTo(".badgeBody");
$(document.createElement("td")).appendTo(".row1");
$(document.createElement("span")).attr("class", "badgeUnlocked").text("UNLOCKED! ").appendTo("td");
$(document.createElement("td")).attr("class", "badgeTitleText").appendTo(".row1");
$(document.createElement("span")).attr("class", "badgeTitle").text(name).appendTo(".badgeTitleText");
$(document.createElement("tr")).attr("class", "row2").appendTo(".badgeBody");
$(document.createElement("td")).appendTo(".row2");
$(document.createElement("img")).attr("src", imgUrl).appendTo(".row2 td");
$(document.createElement("td")).attr("class", "badgeText").appendTo(".row2");
$(document.createElement("span")).attr("class", "badgeDescription").text(description).appendTo(".badgeText");
Это может быть грубо, так как appendTo хочет добавить к каждому соответствующему элементу, чтобы все нуждалось в собственном имени, иначе оно будет постоянно добавляться по всему месту.
Затем я попытался создать массив и объединить его:
var badgeFragment = [
'<div><div id="'+ closeId+'" class="closeTab">X</div>',
'<div id="'+ badgeId+'" class="wrapper1">',
'<div class="wrapper2">',
'<div class="badgeBody">',
'<div class="badgeImage">',
'<img src="'+ imgUrl +'">',
'</div>',
'<div class="badgeContents">',
'<div class="badgeUnlocked">ACHIEVEMENT UNLOCKED: </div>',
'<div class="badgeTitle">'+ name +'</div>',
'<div id="'+ textId+'" class="badgeDescription">'+ description +'</div>',
'</div>',
'<div style="clear:both"></div>',
'</div></div></div></div></div>',
]
badgeFragment = $(badgeFragment.join(''));
Это работает очень хорошо, хотя в IE, когда я бы поставил предупреждение ($ (badgeFragment).text()), он обычно возвращался пустым. (Это было частью отладки более крупной проблемы). Я, очевидно, немного новичок в jQuery (и даже Javascript), поэтому, чтобы попытаться убедиться, что это не проблема, я попробовал третий метод - гигантское конкатенация строк:
var badgeFragment =
'<div><div id="'+ closeId+'" class="closeTab">X</div>' +
'<div id="'+ badgeId+'" class="wrapper1">' +
'<div class="wrapper2">' +
'<div class="badgeBody">' +
'<div class="badgeImage">' +
'<img src="C:/Users/Ryan/Documents/icons/crystal_project/64x64/apps/chat.png">' +
'</div>' +
'<div class="badgeContents">' +
'<div class="badgeUnlocked">ACHIEVEMENT UNLOCKED: </div>' +
'<div class="badgeTitle">test</div>' +
'<div id="'+ textId+'" class="badgeDescription">test</div>' +
'</div>' +
'<div style="clear:both"></div>' +
'</div></div></div></div></div>';
Является ли один из этих методов лучше, чем другие? Я не очень хорошо разбираюсь в различных профилировщиках, поэтому я не уверен, как это проверить. Существует также вопрос о том, совместимы или нет все эти методы, совместимые с браузером.
Ответы
Ответ 1
С помощью jQuery 1.4 вы можете создавать HTML-элементы следующим образом:
// create an element with an object literal, defining properties
var e = $("<a />", {
href: "#",
"class": "a-class another-class", // you need to quote "class" since it a reserved keyword
title: "..."
});
// add the element to the body
$("body").append(e);
Здесь ссылка на документацию.
Я не уверен, что этот подход работает быстрее, чем с помощью функции html()
jQuery. Или быстрее, чем пропустить jQuery все вместе и использовать свойство innerHTML
для элемента. Но что касается читаемости; jQuery-подход - мой любимый. И в большинстве случаев прирост производительности при использовании innerHTML
является незначительным.
Ответ 2
Вам не нужно вызывать document.createElement:
$('#existingContainer').append(
$('<div/>')
.attr("id", "newDiv1")
.addClass("newDiv purple bloated")
.append("<span/>")
.text("hello world")
);
В jQuery есть всевозможные полезные инструменты для расширения/смены DOM. Посмотрите на различные методы "wrap", например.
Другая возможность: для действительно больших капель нового контента вам может быть лучше, если ваш сервер подготовит их (используя серверную систему шаблонов, что бы вы ни делали) и выборка с помощью $.load()
или другого ajax подход.
Ответ 3
Я бы склонен смотреть на один из шаблонов для jquery, например jQote
Ответ 4
Джон Ресиг (создатель jQuery) предложил использовать этот шаблонный метод еще в 2008 году. На самом деле у него были довольно интересные функции:
<script type="text/html" id="item_tmpl">
<div id="<%=id%>" class="<%=(i % 2 == 1 ? " even" : "")%>">
<div class="grid_1 alpha right">
<img class="righted" src="<%=profile_image_url%>"/>
</div>
<div class="grid_6 omega contents">
<p><b><a href="/<%=from_user%>"><%=from_user%></a>:</b> <%=text%></p>
</div>
</div>
</script>
затем извлекая его, используя...
var results = document.getElementById("results");
results.innerHTML = tmpl("item_tmpl", dataObject);
См. здесь для полной информации:
http://ejohn.org/blog/javascript-micro-templating/
Ответ 5
Я лично считаю, что для кода важнее читать и редактировать, чем выполнять. Независимо от того, что вам легче смотреть и вносить изменения, не нарушая его, должен быть тот, который вы выберете.
Ответ 6
Мне нравится язык шаблонов Handlebars.js
Ответ 7
Это более читаемый и поддерживаемый, если код JavaScript похож на структуру тегов HTML. Вы можете перейти на официальный маршрут jQuery, используя $('div', {'class': 'etc'})...
Вот несколько другой подход с использованием функции $$, чтобы каждый элемент редактировал объект jQuery. Это должно быть довольно быстро, так как нет разбора html.
$$('div', {'id':'container'},
$$('div', {'id':'my_div'},
$$('h1',{'class':'my_header'},
$$('a',{'href':'/test/', 'class':'my_a_class'}, 'teststring'))));
Это делает подход более гибким, и вы можете добавлять обработчики событий, данные и т.д. к вложенным объектам jQuery, используя цепочку довольно легко, например.
$$('div', {'id':'container'},
$$('div', {'id':'my_div'},
$$('h1',{'class':'my_header'},
$$('a', { 'href': '/test/', 'class': 'my_a_class' }, 'teststring')
).click(function() { alert('clicking on the header'); })
).data('data for the div')
).hide();
Код более читабельен, чем если бы использовался официальный jQuery-подход для выполнения его с отдельными вызовами .append(),.text(),.html() и т.д. или путем подачи jQuery $конкатенированного HTML-кода строка.
Справочная функция $$:
function $$(tagName, attrTextOrElems) {
// Get the arguments coming after the params argument
var children = [];
for (var _i = 0; _i < (arguments.length - 2) ; _i++) {
children[_i] = arguments[_i + 2];
}
// Quick way of creating a javascript element without JQuery parsing a string and creating the element
var elem = document.createElement(tagName);
var $elem = $(elem);
// Add any text, nested jQuery elements or attributes
if (attrTextOrElems) {
if (typeof attrTextOrElems === "string") { // text
var text = document.createTextNode(attrTextOrElems);
elem.appendChild(text);
}
else if (attrTextOrElems instanceof jQuery) { // JQuery elem
$elem.append(attrTextOrElems);
}
else // Otherwise an object specifying attributes e.g. { 'class': 'someClass' }
{
for (var key in attrTextOrElems) {
var val = attrTextOrElems[key];
if (val) {
elem.setAttribute(key, val);
}
}
}
}
// Add any further child elements or text
if (children) {
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (typeof child === "string") { // text
var text = document.createTextNode(child);
elem.appendChild(text);
} else { // JQuery elem
$elem.append(child);
}
}
}
return $elem;
}
Ответ 8
То, как я делаю, показано ниже. Я не уверен, что u должен создать так много div, но он работал очень хорошо со мной.
var div1 = $('<div class="colwrap_fof"></div>'); //THE COMPLEX DIV ITSELF
var div2 = $('<div class="homeimg"></div>');
var div21 = $('<div id="backImageDiv'+fof_index+'" class="backDiv"></div>');
var div22 = $('<div id="frontImageDiv'+fof_index+'" class="frontDiv"></div>');
div2.append(div21);
div2.append(div22);
div1.append(div2);
$("#df_background").append(div1); // ADDING the complex div to the right place
Приветствия,