【问题标题】:Is there any clean way to grab an HTML template placed in the <head> using jQuery?是否有任何干净的方法可以使用 jQuery 获取放置在 <head> 中的 HTML 模板?
【发布时间】:2013-04-03 23:18:45
【问题描述】:

根据 Nicholas Zaka 的“可维护的 JavaScript”一书,我知道在我的页面中放置一个小型 HTML 模板的最佳方法是添加如下内容:

    <script type="text/x-templates" class="templates">
            <div class="template1"> ... </div>
            <div class="template2"> ... </div>
            ...
    </script>

我更喜欢这种方法,而不是将我的模板放在 &lt;body&gt; 中并使用 css 隐藏它们,因为这些仍然会显示在像 dillo 这样的浏览器中。

我目前使用 jQuery 获取它们的方式是这样的:

    var $templates = $('<div/>').append($('.templates').text()).children();

我尝试过但不起作用的事情是:

    var $templates = $('.templates');
    var $templates = $($('.templates').text());
    var $templates = $($('.templates').html());

我现在的解决方案有效,但对我来说似乎不是很优雅。最好的方法是什么?

【问题讨论】:

  • 你应该在 Google jquery html 模板中尝试过这 3 个关键字 ---> stephenwalther.com/archive/2010/11/30/…
  • 他可能更喜欢扮演自己的角色。
  • 是的,我想尽可能避免使用额外的依赖项,但感谢您的链接。
  • 使用 html() 而不是 text() 。如果你有多个,$('.templates').html() 只会从该类的第一个返回 html

标签: jquery html client-side-templating


【解决方案1】:

如果“模板”类的内部 HTML 以空格开头,$($('.templates').html()) 将会遇到困难,因此您需要 $($('.templates').html().trim()) 代替。你最终会遇到更多麻烦,因为你的脚本标签的内部 HTML 没有根节点,所以你需要类似的东西:

<script type="text/x-templates" class="templates">
    <div>
        <div class="template1">temp1</div>
        <div class="template2">temp2</div>
        ...
    </div>
</script>

然后您可以使用以下内容获取 template1 的 HTML:

var templatesCollection = $($(".templates").html().trim());
alert(templatesCollection.children(".template1").html());

但是,说了这么多,为什么不把每个模板放在自己的带有ID的脚本标签中呢? (除非您计划拥有多个实例,否则类没有多大意义,并且在模板场景中,我认为这不是您想要的。)

所以更像是:

<script type="text/html" id="template1">
   <div>temp1</div>
</script>

然后是一个非常简单的选择器:$("#template1").html()

【讨论】:

  • 嗨 Snixtor,感谢您的回复。你是对的,我应该为此目的使用 id。我一直在尝试使用单独的脚本标签的方法,但最终遇到了同样的问题。如果我使用 .html() 我不会得到一个 jQuery 对象。我也尝试过 $("#template1").children() 但由于它将内容视为文本,因此找不到任何内容。
  • 您可以在$('html_text_here') 中包装一个html 字符串,但有一些限制。正如我上面提到的,它不能以空格开头,所以你需要修剪它,它还需要一个根节点。 - 当我说根节点时,我的意思是 jQuery 对象需要表示单个元素(尽管该元素可能有子元素)。
  • 哎呀我忘了trim()。好的,是的,这似乎是最好的方法。因此,如果我正确理解它,只要我将每个模板放在单独的 &lt;script&gt; 上,我就可以安全地使用 $($('#idofthetemplate').html().trim());
  • 如果idofthetemplate 元素的内部 HTML 有一个 root 元素,是的。否则你不会得到一个有意义的 jQuery 对象。你会得到一个,但它的内容可能不是你所期望的。
【解决方案2】:

试试这个:

var $templateHtml = $('.templates').html();
var $templates    = $('<div/>').html(templateHtml);

或者,将其设为一行:

var $templates    = $('<div/>').html($('.templates').html());

【讨论】:

    【解决方案3】:

    编辑:我想我最初误解了您的问题 - 我没有意识到您在同一 script 标记中有 多个 模板。我建议将每个模板分成它自己的标签,因为这可能更容易管理(然后你没有额外的解析和 div 标签来保持它们分开)。例如,为您的模板标记考虑这个:

    <script type="text/x-templates" class="template" id="template1">
        [template 1]
    </script>
    
    <script type="text/x-templates" class="template" id="template2">
        [template 2]
    </script>
    

    在你的 JavaScript 中有这样的东西:

    // create a map of templates (keyed by the template's id)
    var templates = {};
    $('.template').each(function() {
        var $template = $(this);
        templates[$template.attr('id')] = $(this).html();
    });
    
    //usage
    $('body').append(templates.template1);
    $('body').append(templates.template2);
    

    这是一个实际的演示:http://jsfiddle.net/KyWj6/

    【讨论】:

    • 感谢 jmar777,我喜欢将所有模板包装为单个对象的想法。为了遵循 Snixtor 的建议,我将templates[$template.attr('id')] = $(this).html(); 更改为templates[$template.attr('id')] = $($(this).html().trim());
    • trim() 是个好主意。你确定你希望模板映射到 jQuery 对象而不是字符串吗?我问是因为那时您正在处理有状态的 DOM 片段,并且可能会产生意想不到的后果。字符串永远不会有那种“陷阱”。
    • 嗯,这是一个很好的观点,但我想这提出了一个不同的问题
    猜你喜欢
    • 2011-07-28
    • 1970-01-01
    • 2020-02-27
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    相关资源
    最近更新 更多