重构HTML生成JavaScript

时间:2008-10-29 15:50:18

标签: javascript html string-concatenation

不幸的是,在我的项目中,我们在JavaScript中生成了很多HTML代码:

var html = new StringBuffer();
html.append("<td class=\"gr-my-deals\"><a href=\"").append(deal.url).append("\" target=\"_blank\">").append(deal.description).append("</a></td>");

我有两个具体的抱怨:

  1. 在HTML字符串中使用转义双引号(\“)。这些应该用单引号(')代替,以提高可读性。
  2. 使用.append()代替JavaScript字符串连接运算符“+”
  3. 应用这两个建议,产生以下等效代码行,我认为这些代码行更具可读性:

    var html = "<td class=’gr-my-deals’><a href=’" + deal.url + "’ target=’_blank’>" + deal.description + "</a></td>";
    

    我现在正在寻找一种方法来自动将第一行代码转换为第二行代码。到目前为止,我想出的就是运行以下查找并替换我们所有的Javascript代码:

    Find:    ).append(  
    Replace: +
    

    这会将上面显示的代码行转换为:

    html.append("<td class=\"gr-my-deals\"><a href=\"" + deal.url + "\" target=\"_blank\">" + deal.description + "</a></td>)";
    

    这应该安全地删除除第一个'append()'语句之外的所有语句。不幸的是,我想不出任何安全的方法来自动将转义的双引号转换为单引号。请记住,我不能简单地进行查找/替换,因为在某些情况下,您确实需要使用转义双引号。通常,这是在您生成包含嵌套JS的HTML时,并且JS包含字符串参数,例如

    function makeLink(stringParam) {
    
      var sb = new StringBuffer();
      sb.append("<a href=\"JavaScript:myFunc('" + stringParam + "');\">");
    }
    

    我的问题(最后)是:

    • 是否有更好的方法可以使用'+'
    • 安全地替换'append()'的调用
    • 有没有办法用单引号安全地替换转义的双引号,正则表达式?

    干杯, 唐

5 个答案:

答案 0 :(得分:4)

考虑切换到JavaScript template processor。它们通常相当轻巧,并且可以显着提高代码的清晰度......以及性能,如果您有大量的重用并选择预编译模板。

答案 1 :(得分:2)

这是一个stringFormat函数,有助于消除连接和丑陋的替换值。

function stringFormat( str ) {

    for( i = 0; i < arguments.length; i++ ) {
        var r = new RegExp( '\\{' + ( i ) + '\\}','gm' );

        str = str.replace( r, arguments[ i + 1 ] );    
    }
    return str;
}

像这样使用:

var htmlMask = "<td class=’gr-my-deals’><a href=’{0}’ target=’_blank’>{1}</a></td>";

var x = stringFormat( htmlMask, deal.Url, deal.description ); 

答案 2 :(得分:1)

正如Shog9所暗示的那样,有几个很好的JavaScript模板引擎。以下是您将如何使用我的示例jQuery Simple Templates

var tmpl, vals, html;

tmpl  = '<td class="gr-my-deals">';
tmpl += '<a href="#{href}">#{text}</a>';
tmpl += '</td>';

vals  = {
    href : 'http://example.com/example',
    text : 'Click me!'
};

html  = $.tmpl(tmpl, vals);

答案 3 :(得分:0)

你有充足的理由在JavaScript中使用StringBuffer()而不是字符串连接。 StringBuffer()及其append()方法使用Array和Array的join()将字符串组合在一起。如果你想要加入大量的部分字符串,那么这就知道这是一种更快的方法。

答案 4 :(得分:0)

模板?模板糟透了!这是我编写代码的方式:

TD({ "class" : "gr-my-deals" },
   A({ href : deal.url,
       target : "_blank"},
     deal.description ))

我使用一个名为DOMination的20行库,我将发送给任何要求支持此类代码的人。

优点是多方面的,但最明显的一些是:

  • 清晰易读的代码
  • 易于学习和编写
  • 紧凑代码(没有关闭标签,只是近括号)
  • 易于理解的JavaScript编辑器,缩小器等
  • 解决了一些特定于浏览器的问题(例如,在IE上的rowSpan和rowspan之间的区别)
  • 与CSS
  • 完美整合

(你的例子,BTW,强调了DOMination的唯一缺点:在这种情况下,任何HTML保留词,class都必须被引用,以免发生坏事。)