Подтвердить что ты не робот

Лучшая практика для вставки больших кусков HTML в элементы с Javascript?

Я создаю веб-приложение (используя прототип), которое требует добавления больших кусков HTML в DOM. Большинство из них - это строки, содержащие элементы со всеми атрибутами.

В настоящее время я сохраняю пустую строку HTML в переменной и

var blankRow = '<tr><td>'
    +'<a href="{LINK}" onclick="someFunc(\'{STRING}\');">{WORD}</a>'
    +'</td></tr>';

function insertRow(o) {
    newRow = blankRow
        .sub('{LINK}',o.link)
        .sub('{STRING}',o.string)
        .sub('{WORD}',o.word);
    $('tbodyElem').insert( newRow );
}

Теперь это хорошо работает и денди, но это лучшая практика?

Мне нужно обновить код в blankRow, когда я обновляю код на странице, поэтому новые вставленные элементы одинаковы. Он становится сосательным, когда у меня есть 40 строк HTML, чтобы идти в пустое окно, а затем мне тоже нужно избегать этого.

Есть ли более простой способ? Я думал о urlencoding, а затем расшифровывал его перед вставкой, но это все равно означало бы blankRow и много побегов.

Что означало бы эхо-функция a la PHP и др.

$blankRow = <<<EOF
text
text
EOF;

Это означало бы отсутствие экранирования, но для этого все равно понадобилось бы 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('<b>Stuff</b>')
    )
    .insert( $p({
        id: 'a-p'})
        .insert('<b>More stuff</b>')
    );

$('parentDiv').insert(newPart);

См. мое решение здесь или здесь.

4b9b3361

Ответ 1

это лучшая практика?

Нет. На самом деле у вас проблемы с HTML-инъекциями, приводящие к ошибкам, а в худшем случае, когда введенные строки могут содержать содержимое, отправленное пользователем, дыры в безопасности XSS.

Когда вы помещаете текстовое содержимое и значения атрибутов в строку HTML, вы должны кодировать HTML-код. В PHP вы должны вызвать htmlspecialchars() для строк, идущих в HTML, чтобы сделать это. В JavaScript вы не получаете встроенную функцию HTML-экранирования, поэтому вам нужно сделать свой собственный, например. используя s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;') в строке, идущей в HTML.

OnClick = "SomeFunc (\ '{СТРОКА} \');"

Это совершенно новый уровень побега. В строковом литерале 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()) для обработки событий без привязки к новым узлам при добавлении.

Ответ 2

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

Альтернативное, по-видимому, чистое решение состоит в том, чтобы встроить в javascript элементы DOM, которые вы должны использовать, вызывая несколько

document.createElement(тэгу);

Но ваш код будет быстро расти, в моей мысли, для ничего.

Еще один мой любимый способ создания DOM - разместить внутри тела HTML код, который вы хотите скопировать, дать ему имя класса и/или идентификатор типа "шаблон", который дополнительно (с помощью css) скроет его, а затем обрабатывать его по мере необходимости на событии, возвращая элемент, клонируя его и устанавливая свойство, которое вы хотите, перед добавлением, где оно принадлежит

Ответ 3

Если я вас хорошо понимаю, ваш вопрос заключается в инициализации больших строк так, как вы это сделаете в 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';

EDIT на основе комментария: я тоже ленив! Поэтому я использую это для экранирования:

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('');

Проблема с ленивым: это довольно тяжелая работа для сохранения ленивости