【问题标题】:jQuery template() for putting a URL into src= attribute of image用于将 URL 放入图像的 src= 属性的 jQuery 模板()
【发布时间】:2011-04-26 17:03:32
【问题描述】:

我有一个 jquery 模板:

<div id="test_template">
    <img src="${url}" width="31" height="32" alt="" />
    ${url}
</div>

我用这个编译它:

test_template = $('#test_template').template();

我用这个来渲染它:

$.tmpl(test_template, {url:'http://sstatic.net/stackoverflow/img/sprites.png'}).appendTo('#render_test');

最终结果是这样的:

<div id="render_test">
<img height="32" width="31" alt="" src="$%7Burl%7D">   http://sstatic.net/stackoverflow/img/sprites.png</div>

显然,我希望 URL 位于 src="" 标记中……但事实并非如此(尽管它在标记之后正确输出)。如果我查看由 template() 创建的匿名函数,我发现它没有将 src="${url}" 转换为 javascript。它只是将其编码为 HTML 并将其吐回

我做错了什么?

【问题讨论】:

    标签: jquery jquery-templates


    【解决方案1】:

    我做错了什么?

    使用真实的&lt;img&gt;

    当您使用&lt;img src&gt; 之类的属性时,浏览器可能会修正您的值以使其有效。因此,由于字符{} 在 URL 中无效,浏览器可能会将它们编码为%7B%7D。这可能是特定于浏览器的;尼克的例子,他说我在 Firefox 中失败了。 (由于test_template 上缺少var,它在 IE 中也失败了,但这是一个不相关的问题。)

    请记住,当您编写 HTML 元素时,不会维护 HTML 源代码。浏览器会将其解析为大量 DOM 节点。当您调用 html() (innerHTML) 时,您得到的是这些 DOM 节点的序列化,它不会完全保留原始标记的格式。特别是当原始标记不是真正有效的 HTML 而只是模板的占位符时。

    出于这个原因,我不会使用实际的页面内元素来作为模板,我认为 jquery-tmpl 用它的$(element).template() 方法鼓励这样做是一个错误。这不是我使用插件的唯一问题。例如,如果您将data() 或事件处理程序放在模板内的元素上,则由于天真的innerHTML 复制和jQuery 可怕的节点身份黑客攻击,该数据/处理程序会被意外复制到IE 而不是其他浏览器上。

    因此,如果您必须使用jquery-tmpl,请使用字符串,而不是节点。如果必须,请使用嵌入在 &lt;script&gt; 中的字符串,但不要使用实际的页内元素。 (除了这个问题之外,在文档中包含不是实际内容的内容在语义上也是有问题的。)

    【讨论】:

      【解决方案2】:

      确保您使用的是最新版本的模板插件,我使用最新的插件和 jQuery 1.4.2 或 1.4.3 都没有问题。

      You can see the working demo of your code here.

      【讨论】:

      • 谢谢尼克。如果我将模板包装器更改为使用
      • 不,我有 jquery 1.4.2,我刚刚从这里获得了模板代码:github.com/jquery/jquery-tmpl/blob/master/jquery.tmpl.min.js ... 仍然无法正常工作(除非我使用
      • @Nick - 可能是它所在的上下文,浏览器已经在尝试对该模板的源做一些事情。为了安全起见,我使用&lt;script&gt;标签,因此浏览器甚至不会尝试来解析内容。
      • 好点......无论如何,这最终是正确的答案。谢谢!
      • 是的,但是看看 ff4 中使用相同的 jsfiddle 链接会发生什么,你会得到转义的模板代码,想法?
      【解决方案3】:

      我通过使用 TmplItem 的丑陋 hack 解决了这个问题:

              function fixRenderedTemplate(rendered){
                  var fixArray = [["img", "src"], ["a", "href"]];
                  for (var i=0; i<fixArray.length; i++){
                      var tagName = fixArray[i][0];
                      var attrName = fixArray[i][1];
                      $(tagName, rendered).each(function(index, elem){
                          var data = $(elem).tmplItem().data;
                          var fixTemplate = unescape($(elem).attr(attrName));
                          var url = $.tmpl(fixTemplate, data).text();
                          $(elem).attr(attrName, url);
                      });
                  }
                  return rendered
              }
      

      只需调用渲染模板上的函数

      【讨论】:

        猜你喜欢
        • 2021-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-22
        • 2019-02-23
        相关资源
        最近更新 更多