Я создаю веб-приложение (использующий прототип), который требует добавления больших блоков HTML в DOM. Большинство из них является строками, которые содержат элементы со всем способом атрибутов.
В настоящее время я сохраняю пустую строку HTML в переменной и
var blankRow = ''
+'{WORD}'
+' ';
function insertRow(o) {
newRow = blankRow
.sub('{LINK}',o.link)
.sub('{STRING}',o.string)
.sub('{WORD}',o.word);
$('tbodyElem').insert( newRow );
}
Теперь, когда работы все хорошо и денди, но действительно ли это - лучшая практика?
Я должен обновить код в blankRow, когда я обновляю код на странице, таким образом, новые вставляемые элементы являются тем же. Это получает sucky, когда я имею как 40 строк HTML для входа в blankRow, и затем я должен выйти из него также.
Существует ли более легкий путь? Я думал о urlencoding и затем декодировал его перед вставкой, но это будет все еще означать blankRow и большой выход.
То, что было бы средним, будет функцией eof а-ля PHP и др.
$blankRow = <<
Это не означало бы выхода, но этому все еще будет нужен blankRow.
Что Вы делаете в этой ситуации?
Законченное использование DOMBuilder в прототипе. Никакие другие библиотеки не были необходимы:
$w('a div p span img table thead td th tr tbody tfoot input').each(function(e) {
window['$' + e] = function() {
return new Element(e, arguments[0]);
}
});
newPart = $div({id: 'partition-4'})
.insert( $p()
.insert('Stuff')
)
.insert( $p({
id: 'a-p'})
.insert('More stuff')
);
$('parentDiv').insert(newPart);
это лучшая практика?
Нет. На самом деле у вас есть проблемы с HTML-инъекцией, ведущие к ошибкам, и в худшем случае, когда введенные строки могут содержать отправленный пользователем контент, дыры в безопасности XSS.
Когда вы помещаете текстовое содержимое и значения атрибутов в строку HTML, вы должны закодировать их в HTML.В PHP для этого необходимо вызвать htmlspecialchars ()
для строк, входящих в HTML. В JavaScript у вас нет встроенной функции экранирования HTML, поэтому вам нужно создать свою собственную, например. используя s.replace (/ & / g, '&'). replace (/ g, '<'). replace (/ "/ g, '"')
в строке, входящей в HTML.
onclick = "someFunc (\ '{STRING} \');"
Это совершенно новый уровень избавления от беспорядка. В строковом литерале JavaScript внутри атрибута обработчика событий вам нужно будет JS-кодировать строку ( \
-escaping '
и \
плюс несколько символов Unicode для полноты) и затем HTML-кодируйте результаты. В противном случае строка может выйти за пределы ограничителя строкового литерала и ввести произвольный JS-код. Во всех случаях избегайте встроенных атрибутов обработчика событий, но особенно при создании шаблонов.
Создание содержимого страницы с помощью строк HTML - отстой. Вы, скорее всего, сделаете обходные ошибки и поставите под угрозу безопасность своего приложения. Вместо этого используйте методы, подобные DOM, и вам не о чем беспокоиться. Кажется, вы используете jQuery, поэтому попробуйте ярлыки для создания элемента jQuery 1.4:
$('<tr>').append(
$('<td>').append(
$('<a>', {
href: o.link,
text: o.word,
onclick: function() {
someFunc(o.string);
}
})
)
);
или оставьте пустую строку внутри документа как HTML, но затем скройте ее ( display: none
) или отсоедините ее из документа во время начала ( removeChild
или jQuery detach
).Затем, когда вам нужна новая строка, клонируйте пустую строку и внесите необходимые изменения:
var blankRow= $('#blankRow').detach();
...
var newRow= blankRow.clone();
var link= newRow.find('td>a');
link.attr('href': o.link);
link.text(o.word);
link.click(function() {
someFunc(o.string);
});
Если вы должны создать контент из строковых шаблонов, убедитесь, что ваша функция шаблонов HTML-экранирует каждую замену по умолчанию, и присоединяйте события, выбирая узлы внутри проанализированный контент для вызова click (function () {...})
on. Или используйте делегирование событий (например, jQuery live ()
) для обработки событий без необходимости связываться с новыми узлами при добавлении.
Вы делаете это хорошим способом, и это довольно быстро, учитывая другие манеры.
Альтернативное, предположительно чистое решение - встроить в javascript элементы DOM, которые вы должны использовать, вызвав несколько
document.createElement (tagName);
Но ваш код, на мой взгляд, будет быстро расти для ничего такого.
Еще один, мой любимый способ создания DOM, - это поместить в тело HTML код, который вы хотите скопировать, присвоить ему имя класса и / или идентификатор, например «шаблон», который дополнительно (с помощью css) скроет его. , а затем обработать его по мере необходимости в событии, вернув элемент, клонировав его и задав свойство, которое вы хотите, перед добавлением, где он принадлежит
Если я вас хорошо понимаю, ваш вопрос касается инициализации больших строк так, как вы это делаете в PHP (или Perl, если на то пошло)? Для длинной (многострочной) строки я использую:
var blankRow = [
'a line',
'another line',
'still more lines',
'lines lines lines',
'... etc'
].join('')
Вы также можете использовать обратную косую черту для продолжения, но это может быть немного запутанным:
var blankRow = 'a line\
another line\
still more lines\
lines lines lines\
... etc';
РЕДАКТИРОВАТЬ на основе комментария: Я тоже ленив! Так что я использую это для побега:
function qs(str){
str = str || this || '';
return "'"+str+"'";
}
function qd(str){
str = str || this || '';
return '"'+str+'"';
}
String.prototype.qs = qs;
String.prototype.qd = qd;
// applied:
var blankRow = [
'a line',
'another '+qd('line'),
'still more lines',
'lines '+'lines'.qs()+ ' lines',
'... etc'
].join('');
Проблема с ленью: довольно сложно удержать лень