我有一个正在循环的数组。每次条件为真时,我都想将下面的 HTML
代码的副本附加到具有一些值的容器元素中。
我可以把这个 HTML 放在哪里,以便以一种智能的方式重复使用?
<a href="#" class="list-group-item">
<div class="image">
<img src="" />
</div>
<p class="list-group-item-text"></p>
</a>
jQuery
$('.search').keyup(function() {
$('.list-items').html(null);
$.each(items, function(index) {
// APPENDING CODE HERE
});
});
最佳答案
老问题,但由于问题询问“使用 jQuery”,我想我会提供一个选项,让您在不引入任何 vendor 依赖项的情况下执行此操作。
虽然市面上有很多模板引擎,但它们的许多功能最近都已不受欢迎,其中迭代 (<% for
)、条件 (<% if
) 和转换 (<%= myString | uppercase %>
) 被视为微语言最好的,最坏的反模式。现代模板实践鼓励简单地将对象映射到其 DOM(或其他)表示,例如我们看到的属性映射到 ReactJS 中的组件(尤其是无状态组件)。
您可以依赖的一个属性来将模板的 HTML 与 HTML 的其余部分相邻,即使用非执行 <script>
type
,例如<script type="text/template">
.对于您的情况:
<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>
在加载文档时,阅读您的模板并使用简单的 String#split
对其进行标记。
var itemTpl = $('script[data-template="listitem"]').text().split(/\$\{(.+?)\}/g);
请注意,使用我们的 token ,您可以在交替的 [text, property, text, property]
中获得它。格式。这让我们可以使用 Array#map
很好地映射它。 , 带有映射函数:
function render(props) {
return function(tok, i) { return (i % 2) ? props[tok] : tok; };
}
在哪里 props
可能看起来像 { url: 'http://foo.com', img: '/images/bar.png', title: 'Lorem Ipsum' }
.
假设您已经解析并加载了 itemTpl
如上,你有一个 items
范围内的数组:
$('.search').keyup(function () {
$('.list-items').append(items.map(function (item) {
return itemTpl.map(render(item)).join('');
}));
});
这种方法也只是勉强 jQuery - 您应该能够使用带有 document.querySelector
的 vanilla javascript 采用相同的方法和 .innerHTML
.
jsfiddle
要问自己一个问题:您真的想要/需要将模板定义为 HTML 文件吗?你总是可以组件化 + 重用模板,就像重用大多数你想要重复的东西一样:使用函数。
在 es7-land 中,使用解构、模板字符串和箭头函数,您可以编写非常漂亮的组件函数,可以使用 $.fn.html
轻松加载。上面的方法。
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(''));
哦,最后要注意的是:不要忘记清理传递给模板的属性,如果它们是从数据库中读取的,或者有人可以从你的页面传入 HTML(然后运行脚本等)。
https://stackoverflow.com/questions/18673860/