Создание элемента JQuery DOM vs innerHTML - PullRequest
2 голосов
/ 12 июня 2010

Получив ответ на один из моих вопросов, упомянул , что при создании элементов в jQuery лучше использовать direct DOM element creation вместо innerHTML,Я попытался найти его в Google, но не смог найти хорошую статью со сравнениями.

Я привел этот код ниже в качестве примера, и мне было интересно, может ли кто-нибудь помочь мне переписать его в форме непосредственного создания элемента DOM в надежде, что я также узнаю разницу после этого.

Большое спасибо.

Ответы [ 2 ]

3 голосов
/ 12 июня 2010

Да, избегайте слинга строк HTML. Вы получаете ошибки и потенциально дыры в безопасности межсайтовых скриптов. Например:

'<a href="'+img.parent().attr('href')+'">'

что если URL в родительском href содержит символы, которые являются особыми в этом контексте HTML, например <, " или &? В лучшем случае вы получите недопустимую разметку, которая может сбить браузер; в худшем случае, если URL-адрес поступает от пользователя, возникает проблема безопасности.

(ОК, < и " вряд ли появятся в URL, но очень вероятно, что &. title, который вы вводите в текстовое содержимое, может быть более уязвимым.)

Это большая и возрастающая проблема. Так же, как мы начинаем понимать, как исправлять ошибки HTML-инъекций, возникающие из-за шаблонов на стороне сервера (например, пользователи PHP забывают о htmlspecialchars()), мы теперь представляем множество новых client- side XSS от наивного HTML-хакерства с innerHTML и jQuery's html(). Избегайте.

Вы можете экранировать текст, который вы вставляете в HTML вручную:

function encodeHTML(s) {
    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
}

'<a href="'+encodeHTML(img.parent().attr('href'))+'">'

но на самом деле вам лучше использовать свойства и методы прямого DOM-стиля, которые, поскольку они не включают в себя HTML-разбор, не требуют экранирования. Они называются DOM-style, потому что так работают оригинальные функции HTML DOM Level 1 (которые существовали еще до того, как innerHTML поднял свою уродливую голову):

var a= document.createElement('a');
a.href= this.parentNode.href;
a.appendChild(document.createTextNode(this.title));

В jQuery вы используете attr() и text(), чтобы сделать то же самое:

var a= $('<a></a>');
a.attr('href', $(this).parent().attr('href');
a.text($(this).attr('title'));

А в jQuery 1.4 вы можете сделать это наиболее удобно, используя ярлык создания элемента:

$(this).append(
    $('<p class="cap"></p>').append(
        $('<a></a>', {
            href: $(this).parent().attr('href'),
            text: $(this).attr('title')
        })
    )
);

Это все еще выглядит немного сомнительно, но от какого родителя вы получаете href? Неправильно помещать <p> или другую ссылку внутри ссылки.

2 голосов
/ 12 июня 2010

Вот как вы создаете элементы в jQuery:

var myDiv = $('<div class="my-class"></div>');

А потом вы можете делать все классные вещи с myDiv.

Вот ваш пример:

var img = $(this);
var myP = $('<p class="cap"></p>');
var myA = $('<a></a>');
myA.attr("href",img.parent().attr('href'));
myA.html(img.attr('title'));
myP.append(myA);
this.append(myP);

Это немного многословно, но да.

...