通过javascript动态添加html时分离Javascript和Html

Posted

技术标签:

【中文标题】通过javascript动态添加html时分离Javascript和Html【英文标题】:Separating Javascript and Html, when dynamically adding html via javascript 【发布时间】:2011-02-07 10:44:45 【问题描述】:

我目前正在为列表应用程序构建一个非常动态的表,它基本上将通过 AJAX 执行基本的 CRUD 功能。

我想做的是将视觉设计和 javascript 分离到我可以在不触及 JS 端的情况下更改设计端的程度。这仅适用于设计大致相同的情况(我想将其用于快速原型制作)

这是一个例子。

<table>
<tr><td>record-123</td><td>I am line 123</td><td>delete row</td></tr>
<tr><td>record-124</td><td>I am line 124</td><td>delete row</td></tr>
<tr><td>record-125</td><td>I am line 125</td><td>delete row</td></tr>
<tr><td>add new record</td></tr>
</table>

现在,当我添加一条新记录时,我想插入一行新的html,但我宁愿不把这个html放到javascript文件中。

我正在考虑在页面上,靠近桌子的地方创建这样的一行。

<tr style='visble:none;' id='template-row'><td>record-id</td><td>content-area</td><td>delete row</td></tr>

当我来添加新行时,我在页面中搜索带有 id=template-row 的标签,然后抓取它,对其进行字符串替换,然后将其放在正确的位置页面。

只要设计没有彻底改变,并且我保持占位符字符串不变,这意味着可以快速修改设计而无需接触 js。

任何人都可以就这样的方法提供任何建议吗?

【问题讨论】:

一定要去看看像 John Resig 的模板系统。这些通常解决了很多您不必担心的问题。 你为什么不做你提到的事情并在附近克隆一个 HTML 片段?无论您的页面如何更改,您都需要在某处进行更改:-) 【参考方案1】:

看看John Resig's Micro-Templating。

用途:

<script type="text/html" id="row_tmpl">
    <tr><td><%=id%></td><td><%=content%></td><td>delete row</td></tr>
</script>

<script type="text/javascript" src="templating.js"></script>
<script type="text/javascript">
    (function()
       var dataObject = "id":"myid","content":"some content";
       var html = tmpl("row_tmpl", dataObject);
       // do whatever you want with the new HTML...
    ());
</script>

注意事项 由于有一些 SO 用户理所当然地担心使用这种方法的 XSS 攻击,我只想指出微模板功能提供了规避问题的方法。 &lt;% %&gt; 标签中的任何 javascript 都会被执行。因此,如果您有一个清除恶意内容输入的功能,您可以在这些 &lt;% %&gt; 标记中调用它。

【讨论】:

不幸的是,与大多数使用“微模板”的示例一样,由于content 缺少 HTML 转义,因此引入了客户端跨站点脚本安全漏洞。 想象您的数据对象包含用户输入(通常是这样)。用户决定输入Hello &lt;script&gt;sendToMaliciousServer(document.cookie);&lt;/script&gt;。允许它插入到 HTML 中而不转义 &lt;s,你就有问题了。我们花了很长时间试图让人们修复服务器端的 HTML 注入问题。我们也不要在客户端介绍它们。 正如模板功能允许恶意用户运行一些任意 JS 一样,它允许开发人员运行一些代码来对内容进行 HTML 转义。例如:&lt;%=cleanEvilFromContent(content)&gt; 将插入 cleanEvilFromContent 函数的返回值。 这个有点麻烦,我在.net mvc中使用它,所以我认为tempate中使用的标签是冲突的,我已经改变了但我得到了另一个错误现在。我认为这是正确的想法,但我必须看看我是否可以让它发挥作用。 是的,&lt;% %&gt; 标签在使用 .net 时不起作用。您将需要使用您自己的一组标签(例如&lt;* *&gt;)来更改它们。您需要在模板和 templ 函数中更新它们。【参考方案2】:

抓住它,对其进行字符串替换,然后将其放在页面中的正确位置。

字符串替换?如果它在页面中,那么您已经有了一个 DOM 节点。无需将您的节点序列化为 HTML 字符串,对其进行修改并将其重新解析为 DOM 节点。当您忘记为 HTML 转义文本时,这种方式会带来疯狂和跨站点脚本安全漏洞。

相反,使用cloneNode 获取 DOM 对象的副本,更改您需要的位,然后将其添加到文档中。

<style type="text/css">
    .hidden  display: none; 
</style>

<table id="sometable">
    <tr class="hidden"><td>-</td><td>-</td><td>delete row</td></tr>
</table>
<input type="button" id="sometable-newrow" value="New row"/>

<script type="text/javascript">
    var recordn= 1;

    document.getElementById('sometable-newrow').onclick= function() 
        var table= document.getElementById('sometable');
        var tr= table.rows[0].cloneNode(true);

        tr.className= ''; // remove hiddenness
        tr.cells[0].firstChild.data= 'record-'+recordn;
        tr.cells[1].firstChild.data= 'I am line '+recordn;
        tr.cells[2].onclick= removeRow;

        table.rows[table.rows.length-1].parentNode.appendChild(tr);
        recordn++;
    ;

    function removeRow() 
        var tr= this.parentNode;
        tr.parentNode.removeChild(tr);
    
</script>

【讨论】:

以上是关于通过javascript动态添加html时分离Javascript和Html的主要内容,如果未能解决你的问题,请参考以下文章

更新面板内动态添加的用户控件内部的Javascript函数未定义

根据下拉选择动态填充字段(Javascript / HTML)

通过 PHP 循环动态添加 <img> 标记,通过在每个循环上调用 JavaScript 函数

JS动态添加JavaScript语句

javascript动态添加删除表格

js动态实现时分秒