【问题标题】:jQuery DOM element creation vs innerHTMLjQuery DOM 元素创建与 innerHTML
【发布时间】:2011-03-02 22:59:29
【问题描述】:

在回答了我的一个问题时,cletus mentioned 在 jQuery 中创建元素时最好使用 direct DOM element creation,而不是 innerHTML。我试着用谷歌搜索它,但我找不到一篇比较好的文章。

我在下面提供了这段代码作为示例,我想知道是否有人可以帮助我以直接 DOM 元素创建形式重写它,希望我之后也能了解其中的区别。

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

非常感谢。

【问题讨论】:

  • Mohammad:@cletus 也有这个原因:一些浏览器在使用 innerHTML 类型的方法创建标记时异常缓慢,所以我倾向于使用上述方法,它使用 diretc DOM 元素创建.
  • 实际上有一个performance tool 可以用来测试各种浏览器。同样,T.J. Crowder 写了一个quick summary 的innerHTML 的优点和缺点。我个人从来没有觉得使用 innerHTML 很舒服,尽管我发现清除 div 的内容比重复删除子节点更快。我很惊讶实际上有充分的理由使用它。 (我不知道为什么我之前发布了这个作为“答案”)

标签: jquery dom comparison innerhtml


【解决方案1】:

是的,避免使用 HTML 字符串。您给自己带来了错误和潜在的跨站点脚本安全漏洞。例如:

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

如果父 href 中的 URL 包含此 HTML 上下文中的特殊字符,如 &lt;"&amp;,该怎么办?充其量你会得到可能会使浏览器出错的无效标记;最坏的情况是,如果 URL 来自用户提交,则会出现安全问题。

(好的,&lt;" 不太可能出现在 URL 中,但 &amp; 确实很可能出现。您在文本内容中输入的 title 可能更容易受到攻击。)

这是一个日益严重的大问题。正如我们开始着手修复来自服务器端模板的 HTML 注入错误(例如,PHP 用户忘记htmlspecialchars()),我们现在引入了大量新的 client-使用innerHTML 和 jQuery 的html() 进行简单的 HTML 黑客攻击 XSS。避免。

可以转义您手动插入 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 样式,因为这是原始 DOM 1 级 HTML 功能的工作方式(早在 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?在链接中放置&lt;p&gt; 或其他链接是无效的。

【讨论】:

  • 谢谢! bobince,在我附加 &lt;p&gt; 之前,我将图像和它的父级:&lt;a&gt; 包装在 &lt;div&gt; 内,这也成为新目标,正如您在我的更新中看到的 j.mp/bVk1J1
  • 关于同样的注释,targetPar.wrap('&lt;div class="photo"&gt;&lt;/div&gt;'); 是这种方法的最佳实现吗?再次感谢您的详尽回答!
  • 是的,在包装 HTML 中包含静态 class="photo" 就可以了。 title 肯定比 alt 更适合放置类似标题的信息。
  • bobince,我认为您的最后一个代码有语法错误。它在参数列表后显示“缺少 )”
【解决方案2】:

这是在 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);

这有点冗长,但是是的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多