首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Javascript将大量HTML插入元素的最佳实践是什么?

使用Javascript将大量HTML插入元素的最佳实践是什么?
EN

Stack Overflow用户
提问于 2010-05-15 19:00:10
回答 3查看 9.2K关注 0票数 18

我正在构建一个web应用程序(使用prototype),它需要将大量的HTML添加到DOM中。其中大多数是包含具有各种属性的元素的行。

目前,我在一个变量中保留了一个空白的HTML行,

代码语言:javascript
复制
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中的代码,所以插入的新元素是相同的。当我在一个blankRow中有40行超文本标记语言时,它变得很糟糕,然后我也不得不转义它。

有没有更简单的方法?我在考虑对blankRow进行编码,然后在插入之前对其进行解码,但这仍然意味着but和大量转义。

这意味着什么将是一个类似PHP等人的eof函数。

代码语言:javascript
复制
$blankRow = <<<EOF
text
text
EOF;

这将意味着无法转义,但它仍然需要一个blankRow。

在这种情况下你会怎么做?

已解决

最终在prototype中使用了DOMBuilder。不需要其他库:

代码语言:javascript
复制
$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);

请参阅我的解决方案herehere

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-05-15 20:08:27

这是最佳实践吗?

不是的。事实上,您已经遇到了导致bug的HTML注入问题,在最糟糕的情况下,注入的字符串可能包含用户提交的内容,XSS安全漏洞。

将纯文本内容和属性值放入HTML字符串中时,必须对它们进行HTML编码。在PHP中,你必须在进入超文本标记语言的字符串上调用htmlspecialchars()。在JavaScript中,你没有得到一个内置的超文本标记语言转义函数,所以你必须创建自己的函数,例如。通过对进入超文本标记语言的字符串使用s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;')

字符串onclick="someFunc(\'{STRING}\');“

这是一个全新的摆脱混乱的水平。在事件处理程序属性内的JavaScript字符串文本中,必须对字符串进行JS编码(\、-escaping、'\加上几个Unicode字符以保证完整性),然后对结果进行HTML编码。否则,字符串可能会突破其字符串文字分隔符,并注入任意JS代码。在所有情况下都要避免内联事件处理程序属性,尤其是在模板中。

用HTML字符串创建页面内容很糟糕。您很可能会出现转义错误,并危及应用程序的安全性。使用类似于DOM的方法,您不必担心这一点。您似乎正在使用jQuery,因此尝试使用jQuery 1.4元素创建快捷方式:

代码语言:javascript
复制
$('<tr>').append(
    $('<td>').append(
        $('<a>', {
            href: o.link,
            text: o.word,
            onclick: function() {
                someFunc(o.string);
            }
        })
    )
);

或者,将空白行作为HTML语言保留在文档中,然后将其隐藏(display: none)或在开始时将其从文档中分离(removeChild或jQuery detach)。然后,当您需要新行时,克隆空白行并进行所需的更改:

代码语言:javascript
复制
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);
});

如果您必须从字符串模板创建内容,请确保您的模板函数在默认情况下会转义所有替换内容,并通过选择解析内容内的节点来附加事件以调用click(function() { ... })。或使用事件委派(例如,jQuery live())来处理事件,而不必在添加时绑定到新节点。

票数 20
EN

Stack Overflow用户

发布于 2010-05-15 19:20:45

你使用了一种好的方法,考虑到其他方式,这是相当快的。

另一种假定干净的替代解决方案是在javascript中构建要使用的DOM元素,方法是调用几个

document.createElement(tagName);

但在我看来,您的代码将会迅速增长,而且毫无意义。

另一种方法,也是我最喜欢的实现DOM创建的方法,就是将想要复制的代码放在HTML体中,给它一个className和/或一个类似于"template“的id (使用css )来另外隐藏它,然后在事件发生时根据需要处理它,方法是取回元素,克隆它,并设置您想要的属性,然后添加到它所属的位置

票数 5
EN

Stack Overflow用户

发布于 2010-05-15 19:21:18

如果我理解得很好,您的问题是关于初始化大型字符串的方式,就像在PHP (或Perl )中那样?对于我使用的长(多行)字符串:

代码语言:javascript
复制
var blankRow = [
     'a line',
     'another line',
     'still more lines',
     'lines lines lines',
     '... etc'
    ].join('')

你也可以使用反斜杠来继续,但这可能会变得有点混乱:

代码语言:javascript
复制
var blankRow = 'a line\
another line\
still more lines\
lines lines lines\
... etc';

基于评论进行编辑:我也很懒!所以我用这个来进行转义:

代码语言:javascript
复制
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('');

懒惰的问题:坚持一个人的懒惰是相当困难的工作

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2839844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档