使用Javascript将大块HTML插入元素的最佳实践?

ham*_*tar 18 html javascript ajax dom

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

目前,我在变量中保留一行空白的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 );
}
Run Code Online (Sandbox Code Playgroud)

现在一切顺利,花花公子,但这是最好的做法吗?

当我更新页面上的代码时,我必须更新blankRow中的代码,因此插入的新元素是相同的.当我有40行HTML进入blankRow然后我也必须逃避它时,它变得很糟糕.

有没有更简单的方法?我想到了urlencoding,然后在插入之前解码它,但这仍然意味着一个blankRow和许多转义.

什么意思将是PHP等人的eof函数.

$blankRow = <<<EOF
text
text
EOF;
Run Code Online (Sandbox Code Playgroud)

这意味着没有逃脱但它仍然需要一个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);
Run Code Online (Sandbox Code Playgroud)

见我的解决方案在这里在这里.

bob*_*nce 20

这是最好的做法吗?

实际上,你有HTML注入问题导致错误,并且在最坏的情况下,注入的字符串可能包含用户提交的内容,XSS安全漏洞.

将纯文本内容和属性值放入HTML字符串时,必须对它们进行HTML编码.在PHP中,您必须调用htmlspecialchars()进入HTML的字符串来执行此操作.在JavaScript中,你没有内置的HTML转义函数,所以你必须自己创建,例如.通过使用s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;')进入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);
            }
        })
    )
);
Run Code Online (Sandbox Code Playgroud)

或者,将空白行实际保留在文档中作为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);
});
Run Code Online (Sandbox Code Playgroud)

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

  • @hamstar:哎呀!我应该发现这是一个Prototype ID选择器`$`而不是jQuery.D'哦.Prototype有一个类似的(IMO:在某些方面更好)创建元素的快捷方式,`new Element`.见http://prototypejs.org/2007/5/12/dom-builder (2认同)

dad*_*der 5

你用一种好的方式做到这一点,考虑到其他方式,这是非常快的.

一个替代的,假设干净的解决方案是通过调用几个来构建javascript你要使用的DOM元素

使用document.createElement(标签名);

但是,在我的思想中,你的代码将会迅速增长.

另一个,我最喜欢的创建DOM的方法是在HTML体内放置要复制的代码,给它一个className和/或像"模板"这样的id,另外(使用css)隐藏它,然后通过获取元素,克隆它以及在追加它所属的位置之前设置所需的属性,根据事件处理它