jQuery template()用于将URL放入src = image的属性

时间:2010-10-17 22:01:28

标签: jquery jquery-templates

我有一个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并将其吐出来

我做错了什么?

3 个答案:

答案 0 :(得分:2)

  

我做错了什么?

使用真实的<img>

当您使用<img src>等属性时,浏览器可能会修复您的值以使其有效。因为字符{}在网址中无效,浏览器可能会将其编码为%7B%7D。这可能是特定于浏览器的;尼克的例子,他说在Firefox中我的工作失败了。 (由于var上缺少test_template,它在IE中也失败了,但这是一个无关的问题。)

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

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

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

答案 1 :(得分:1)

确保您使用的是最新版本的模板插件,使用最新的插件以及jQuery 1.4.2或1.4.3时没有任何问题。

You can see the working demo of your code here

答案 2 :(得分:0)

我用一个使用TmplItem的丑陋黑客解决了这个问题:

        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
        }

只需在渲染模板上调用该函数