【问题标题】:Is there a best practice for generating html with javascript是否有使用 javascript 生成 html 的最佳实践
【发布时间】:2010-09-18 05:58:03
【问题描述】:

我正在调用一个以 JSON 格式返回对象数组的 Web 服务。我想获取这些对象并用 HTML 填充一个 div。假设每个对象都包含一个 url 和一个名称。

如果我想为每个对象生成以下 HTML:

<div><img src="the url" />the name</div>

对此有最佳实践吗?我可以看到几种方法:

  1. 连接字符串
  2. 创建元素
  3. 使用模板插件
  4. 在服务器上生成 html,然后通过 JSON 提供服务。

【问题讨论】:

  • 你也可以检查下划线js:documentcloud.github.com/underscore/#template 它与backbone.js 配合得很好
  • 选择 1-4:取决于要注入多少内容。(最好是 4 更大)总共需要附加多少不同的 html 部分(3 或 4)。某人熟悉什么。 (对开发时间的影响)。如果你不知道任何工具,它只是一个小的模式,一旦我不知道比纯 js 更好的方法来做它(1-2)

标签: javascript html ajax dynamic dhtml


【解决方案1】:

也许更现代的方法是使用模板语言,例如Mustache,它具有多种语言的实现,包括javascript。例如:

var view = {
  url: "/hello",
  name: function () {
    return 'Jo' + 'hn';
  }
};

var output = Mustache.render('<div><img src="{{url}}" />{{name}}</div>', view);

您甚至可以获得额外的好处 - 您可以在其他地方重复使用相同的模板,例如服务器端。

如果你需要更复杂的模板(if语句、循环等),可以使用Handlebars,它功能更多,兼容Mustache。

【讨论】:

    【解决方案2】:

    披露:我是 BOB 的维护者。

    有一个名为 BOB 的 javascript 库可以让这个过程变得更容易。

    对于您的具体示例:

    <div><img src="the url" />the name</div>
    

    这可以通过以下代码用 BOB 生成。

    new BOB("div").insert("img",{"src":"the url"}).up().content("the name").toString()
    //=> "<div><img src="the url" />the name</div>"
    

    或者使用更短的语法

    new BOB("div").i("img",{"src":"the url"}).up().co("the name").s()
    //=> "<div><img src="the url" />the name</div>"
    

    这个库非常强大,可以用来创建非常复杂的数据插入结构(类似于d3),例如:

    data = [1,2,3,4,5,6,7]
    new BOB("div").i("ul#count").do(data).i("li.number").co(BOB.d).up().up().a("a",{"href": "www.google.com"}).s()
    //=> "<div><ul id="count"><li class="number">1</li><li class="number">2</li><li class="number">3</li><li class="number">4</li><li class="number">5</li><li class="number">6</li><li class="number">7</li></ul></div><a href="www.google.com"></a>"
    

    BOB 目前不支持将数据注入 DOM。这是在todolist上。现在您可以简单地将输出与普通 JS 或 jQuery 一起使用,并将其放在您想要的任何位置。

    document.getElementById("parent").innerHTML = new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s();
    //Or jquery:
    $("#parent").append(new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s());
    

    我制作这个库是因为我对 jquery 和 d3 等任何替代品都不满意。代码非常复杂且难以阅读。和BOB一起工作在我看来,显然是有偏见的,要愉快得多。

    BOB 在 Bower 上可用,因此您可以通过运行bower install BOB 获得它。

    【讨论】:

    • 你做得很好。 :) 虽然我希望在应用复杂场景之前花时间了解它的结构。但是,在我看来,这是最好的解决方案。
    • 谢谢@ImranFaruqi 自从我研究这个库以来已经有很长一段时间了,但它应该可以按预期工作。如果对您有用,请随时提供帮助!
    【解决方案3】:

    对此有最佳实践吗?我可以看到几种方法:

    1. 连接字符串
    2. 创建元素
    3. 使用模板插件
    4. 在服务器上生成 html,然后通过 JSON 提供服务。

    1) 这是一个选项。在客户端用 JavaScript 构建 html,然后将其作为一个整体注入到 DOM 中。

    请注意,这种方法背后有一个范例:服务器只输出数据,并且(在交互的情况下)通过 AJAX 请求从客户端异步接收数据。客户端代码作为独立的 JavaScript Web 应用程序运行。

    即使服务器未启动,Web 应用程序也可以操作、呈现界面(当然它不会显示任何数据或提供任何类型的交互)。

    这种范式最近经常被采用,并且整个框架都是围绕这种方法构建的(例如,参见主干.js)。

    2)出于性能原因,如果可能的话,最好将html构建成一个字符串,然后将其作为一个整体注入到页面中。

    3) 这是另一种选择,以及采用 Web 应用程序框架。其他用户发布了各种可用的模板引擎。我的印象是你有能力评估他们并决定是否走这条路。

    4) 另一种选择。但将其作为纯文本/html 提供;为什么是 JSON?我不喜欢这种方法,因为将 PHP(您的服务器语言)与 Html 混合在一起。但我经常采用它作为选项 14 之间的合理折衷。


    我的回答:你已经在寻找正确的方向了。

    我建议像我一样采用介于 14 之间的方法。否则采用 Web 框架或模板引擎。

    根据我的经验,我的意见...

    【讨论】:

      【解决方案4】:

      选项 #1 和 #2 将是您最直接的直接选项,但是,对于这两个选项,您将通过构建字符串或创建 DOM 对象感受到性能和维护的影响。

      模板并不是那么不成熟,您会在大多数主要的 Javascript 框架中看到它弹出。

      这是JQuery Template Plugin 中的一个示例,它可以为您节省性能损失,并且非常非常简单:

      var t = $.template('<div><img src="${url}" />${name}</div>');
      
      $(selector).append( t , {
           url: jsonObj.url,
           name: jsonObj.name
      });
      

      我说走很酷的路线(性能更好,更易于维护),并使用模板。

      【讨论】:

      • JQuery 模板似乎已死,见stackoverflow.com/questions/7911732/…
      • @Jim Fiorato:链接已失效:s
      • Link 已失效,正如 Adrien 指出的那样。建议您更新您的答案以包括:Mustache.js
      • 有人可以解释一下,为什么基于 jQuery 的答案是公认的答案?我怀疑这是最佳做法!
      • @WoIIe 更糟糕的是,jQuery 插件已经死了,所以这个答案已经过时了。
      【解决方案5】:

      如果你绝对必须连接字符串,而不是正常的:

      var s="";
      for (var i=0; i < 200; ++i) {s += "testing"; }
      

      使用临时数组:

      var s=[];
      for (var i=0; i < 200; ++i) { s.push("testing"); }
      s = s.join("");
      

      使用数组要快得多,尤其是在 IE 中。不久前,我用 IE7、Opera 和 FF 对字符串进行了一些测试。 Opera 只用了 0.4s 就完成了测试,但是 IE7 20 MINUTES 还没有完成!!! (不,我不是在开玩笑。) 用数组 IE 非常快。

      【讨论】:

      • 我很久以前就换了浏览器,所以我没有那么痛苦。 IE 是一个糟糕的浏览器,但它正在变得更好。但我怀疑我会不会转回去。
      • 第一种方法中看到的性能缓慢可能是因为结果字符串必须重新分配 200 次,并且内存分配可能很慢。两次迭代后,您就有了“testingtesting”。三次迭代后,该字符串被丢弃,并分配有足够空间用于“testingtestingtesting”的内存。以此类推200次,长度逐渐增加。然而 s.join() 分配了一个新的字符串,它的长度足以容纳所有字符串,然后复制每个字符串。一次分配,速度更快。
      • @JoeCoder,同意,这是一个 Shlemiel The Painter 算法。 joelonsoftware.com/articles/fog0000000319.html
      【解决方案6】:

      您可以将模板 HTML 添加到隐藏的 div 中的页面中,然后使用 cloneNode 和您喜欢的库的查询工具来填充它

      /* CSS */
      .template {display:none;}
      
      <!--HTML-->
      <div class="template">
        <div class="container">
          <h1></h1>
          <img src="" alt="" />
        </div>
      </div>
      
      /*Javascript (using Prototype)*/
      var copy = $$(".template .container")[0].cloneNode(true);
      myElement.appendChild(copy);
      $(copy).select("h1").each(function(e) {/*do stuff to h1*/})
      $(copy).select("img").each(function(e) {/*do stuff to img*/})
      

      【讨论】:

        【解决方案7】:

        这是一个示例,使用我的 Simple Templates jQuery 插件:

        var tmpl = '<div class="#{classname}">#{content}</div>';
        var vals = {
            classname : 'my-class',
            content   : 'This is my content.'
        };
        var html = $.tmpl(tmpl, vals);
        

        【讨论】:

        • 整洁。几个月前,我本可以在一个大项目中使用类似的东西。
        • 是的。简洁利落!
        【解决方案8】:

        前两个选项中的任何一个都是常见且可接受的。

        我将在Prototype 中给出每个示例。

        // assuming JSON looks like this:
        // { 'src': 'foo/bar.jpg', 'name': 'Lorem ipsum' }
        

        方法#1:

        var html = "<div><img src='#{src}' /> #{name}</div>".interpolate(json);
        $('container').insert(html); // inserts at bottom
        

        方法 #2:

        var div = new Element('div');
        div.insert( new Element('img', { src: json.src }) );
        div.insert(" " + json.name);
        $('container').insert(div); // inserts at bottom
        

        【讨论】:

        • 使用字符串而不是 DOM 元素显式生成 HTML 的构建性能更高(假设字符串连接不是真正的问题)和可读性。
        • 在 IE 中字符串连接总是一个问题。请改用数组。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-06
        • 1970-01-01
        • 2011-07-11
        相关资源
        最近更新 更多