Javascript 使用JQuery定义要追加的HTML模板

Javascript 使用JQuery定义要追加的HTML模板,javascript,jquery,json,Javascript,Jquery,Json,我有一个数组,我正在循环。每次一个条件为true时,我都想将下面的HTML代码的副本附加到一个容器元素中,并带有一些值 在哪里可以智能地重复使用此HTML <a href="#" class="list-group-item"> <div class="image"> <img src="" /> </div> <p class="list-group-item-text"></p>

我有一个数组,我正在循环。每次一个条件为true时,我都想将下面的
HTML
代码的副本附加到一个容器元素中,并带有一些值

在哪里可以智能地重复使用此HTML

<a href="#" class="list-group-item">
    <div class="image">
         <img src="" />
    </div>
    <p class="list-group-item-text"></p>
</a>
在身体的某处添加

<div class="hide">
<a href="#" class="list-group-item">
    <table>
        <tr>
            <td><img src=""></td>
            <td><p class="list-group-item-text"></p></td>
        </tr>
    </table>
</a>
</div>
并添加到您的js中

$('#output').append( $('.hide').html() );

为了解决这个问题,我认识到两种解决方案:

  • 第一个是AJAX,使用AJAX,您必须从另一个文件加载模板,并在需要时添加模板

    考虑到ajax完成后应该添加事件,以确保数据可用

  • 第二种方法是直接将其添加到原始html中的任何位置,选择它并将其隐藏在jQuery中:

    temp = $('.list_group_item').hide()
    
    添加模板的新实例后,可以使用

    $('.search').keyup(function() {
        $('.list-items').html(null);
    
        $.each(items, function(index) {
            $(this).append(temp.clone())
        });
    });
    
  • 与前一个相同,但是如果您不希望模板保留在那里,而只是在javascript中,我认为您可以使用(尚未测试!)而不是隐藏

    temp = $('.list_group_item').detach()
    
    .detach()
    从DOM中删除元素,同时保持数据和事件的活动状态(.remove()不!)


您可以决定在项目中使用模板引擎,例如:

如果您不想包含另一个库,John Resig提供了一个类似于下面的库


浏览器和屏幕阅读器忽略无法识别的脚本类型:

<script id="hidden-template" type="text/x-custom-template">
    <tr>
        <td>Foo</td>
        <td>Bar</td>
    <tr>
</script>
其他备选方案:

我使用它,它帮助了我很多。 他们的网站上显示了一个示例:

HTML

<div class="who">
</div>
结果

<div class="who">
  Hello Wrrrld
</div>

你好,沃尔德

老问题,但由于问题是“使用jQuery”,我想我会提供一个选项,让您在不引入任何供应商依赖性的情况下实现这一点

虽然有很多模板引擎,但它们的许多特性最近都不受欢迎,因为迭代(
使用HTML模板!
由于公认的答案将代表重载脚本方法,我想建议另一种方法,在我看来,它更干净、更安全,因为重载脚本会带来XSS风险

我制作了一个示例,向您展示如何在操作中使用它,以及如何将一个模板插入到另一个模板中,编辑并添加到文档DOM中

示例html HTML<template>
  • +它的内容在被激活之前实际上是惰性的 标记是隐藏的DOM,不会呈现

  • +模板中的任何内容都不会有副作用。在使用模板之前,脚本不会运行,图像不会加载,音频不会播放

  • +内容不在文档中。在主页中使用
    document.getElementById()
    querySelector()
    不会返回模板的子节点

  • +模板可以放在
    中的任何位置,并且可以包含这些元素中允许的任何类型的内容。请注意,“anywhere”表示
    可以安全地用于HTML解析器不允许的位置

退后 浏览器支持不应该是一个问题,但如果您想涵盖所有可能性,可以轻松检查:

要检测特性
,请创建DOM元素并检查 .content属性存在:

关于重载脚本方法的一些见解
  • +未呈现任何内容-浏览器不会呈现此块,因为默认情况下,
    标记具有
    显示:无
  • +惰性-浏览器不会将脚本内容解析为JS,因为其类型设置为除
    “text/javascript”
    之外的其他类型
  • -安全问题-鼓励使用
    .innerHTML
    。对用户提供的数据进行运行时字符串解析很容易导致XSS漏洞
全文:

有用的参考资料:

创建WEB组件Trawersy Media使用HTML模板创建自定义WEB组件教程:

关于使用本机HTML5元素非常好。 为了回答OP中的这个好问题,我想补充一下如何使用jQuery使用这个
模板
元素,例如:

$($('template').html()).insertAfter( $('#somewhere_else') );

模板的内容不是html,只是作为数据处理,因此您需要将内容包装到jQuery对象中,然后才能访问jQuery的方法。

如果您正在寻找一种聪明的方法,请将所有信息放在一个DIV中,并对其进行样式设置。不要创建只有两个单元格的多个表,不要将它们包装到锚中。OP显然是一种错误我对正确的编码实践很感兴趣(很荣幸!),所以我想提供帮助。如果我想对实际问题做出贡献,我会发布一个答案。我相信任何人都同意,使用完整的两格表来定位图像和一些文本几乎是不合理的,除了一些非常奇怪的要求(IE4?)@不过,发表评论并不意味着你真的偏离了正轨。虽然我同意评论是这些评论的合适场所(只要它们仍然相关),它们也适用于那些还没有时间将它们扩展为答案的人的驱动提示。让OP清楚地知道你在做什么对OP很有帮助。没有人回答你的问题,Patrick?--没问题!--OP有一个JSON,希望使用该数组作为数据源呈现一些html。这个答案是如何解决这个问题的?您的答案获取一个html节点并克隆/复制它,与数据绑定无关。我引用op的话:我想将下面的html代码的副本附加到一个带有一些值的容器元素。我相信这解决了他的问题。如何处理“一些值”部分?嗯,这并不意味着它不能解决问题。我很感激你告诉我我遗漏了一点:)不管怎样,如果我甚至不知道我们是什么值,我怎么知道如何插入这些值
var template = $('#hidden-template').html();

$('button.addRow').click(function() {
    $('#targetTable').append(template);
});
<div class="who">
</div>
{
  "who": "Hello Wrrrld"
}
<div class="who">
  Hello Wrrrld
</div>
<script type="text/template" data-template="listitem">
    <a href="${url}" class="list-group-item">
        <table>
            <tr>
                <td><img src="${img}"></td>
                <td><p class="list-group-item-text">${title}</p></td>
            </tr>
        </table>
    </a>
</script>
var itemTpl = $('script[data-template="listitem"]').text().split(/\$\{(.+?)\}/g);
function render(props) {
  return function(tok, i) { return (i % 2) ? props[tok] : tok; };
}
$('.search').keyup(function () {
  $('.list-items').append(items.map(function (item) {
    return itemTpl.map(render(item)).join('');
  }));
});
const Item = ({ url, img, title }) => `
  <a href="${url}" class="list-group-item">
    <div class="image">
      <img src="${img}" />
    </div>
    <p class="list-group-item-text">${title}</p>
  </a>
`;
$('.list-items').html([
  { url: '/foo', img: 'foo.png', title: 'Foo item' },
  { url: '/bar', img: 'bar.png', title: 'Bar item' },
].map(Item).join(''));
<template id="mytemplate">
  <style>
     .image{
        width: 100%;
        height: auto;
     }
  </style>
  <a href="#" class="list-group-item">
    <div class="image">
      <img src="" />
    </div>
    <p class="list-group-item-text"></p>
  </a>
</template>
// select
var t = document.querySelector('#mytemplate');

// set
t.content.querySelector('img').src = 'demo.png';
t.content.querySelector('p').textContent= 'demo text';

// add to document DOM
var clone = document.importNode(t.content, true); // where true means deep copy
document.body.appendChild(clone);
function supportsTemplate() {
  return 'content' in document.createElement('template');
}

if (supportsTemplate()) {
  // Good to go!
} else {
  // Use old templating techniques or libraries.
}
$($('template').html()).insertAfter( $('#somewhere_else') );