我正在尝试使用grunt-contrib-html来缩小我的html。我使用无容器控制流语法的唯一问题,这只是html注释,但它们对knockout非常重要:
<ul>
<li>This item always appears</li>
<!-- ko if: someExpressionGoesHere -->
<li>I want to make this item present/absent dynamically</li>
<!-- /ko -->
</ul>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
所以当我用以下选项使用minifier时:
options: {
removeComments: true,
collapseWhitespace: true
}
应用程序在缩小后不工作(不奇怪,它删除了<!-- ko comments
)。删除removeComments
解决了问题,但我的html有很多评论,只有少数是击倒特定的。而且所有的敲除注释都很容易识别:它们的开头是<!-- ko
,最后是<!-- /ko -->
。
寻找底层的html minifier选项-没有什么比"正确处理knockout注释"更好的了。
所以有一种方法来解决我的问题:最小化html删除评论,但留下击倒特定的评论?
所以…这现在是通过ignoreCustomComments
选项实现的。
下面是我们测试套件中的一个片段:
var input = '<!-- ko if: someExpressionGoesHere --><li>test</li><!-- /ko -->';
equal(minify(input, {
removeComments: true,
// ignore knockout comments
ignoreCustomComments: [
/^s+ko/,
//kos+$/
]
}), input);
如果出于某种原因,您仍然希望使用无容器控制流而不在代码中添加注释标记,那么我已经编写了一个绑定处理程序来为您完成此操作。
像这样应用:
<div data-bind="wrap: {foreach: arr}" data-bind-inner="text: $data"></div>
,容器的绑定作为data-bind
属性,元素本身的绑定作为data-bind-inner
属性。处理程序实际上创建注释标记并对其应用指定的绑定,因此没有什么真正棘手的事情发生。
ko.bindingHandlers.wrap = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var outerBinding = valueAccessor(),
vNodeOpen = document.createComment('ko'),
vNodeClose = document.createComment('/ko');
element.dataset.bind = element.dataset.bindInner;
// Enclose element in comment nodes
element.parentNode.insertBefore(vNodeClose, element);
element.parentNode.insertBefore(element, vNodeClose);
element.parentNode.insertBefore(vNodeOpen, element);
ko.applyBindingsToNode(vNodeOpen, outerBinding, bindingContext);
}
};
演示小提琴如前所述,它适用于单个节点(当然还有它的后代节点);您不能包装一对兄弟姐妹,但它可以扩展为采用siblingCount
选项。