Knockout.js I';我对淘汰赛有意见';在移除回调和CSS转换之前
我正在使用foreach绑定和beforeRemove回调来设置删除列表项的动画。当我移除之前移除的项目上方的项目时效果良好,但当我尝试移除之前移除的项目下方的项目时,转换无法正常工作 下面是一个JSFIDLE来说明我的问题: HTML JSKnockout.js I';我对淘汰赛有意见';在移除回调和CSS转换之前,knockout.js,Knockout.js,我正在使用foreach绑定和beforeRemove回调来设置删除列表项的动画。当我移除之前移除的项目上方的项目时效果良好,但当我尝试移除之前移除的项目下方的项目时,转换无法正常工作 下面是一个JSFIDLE来说明我的问题: HTML JS 函数vm(){ “严格使用”; var me=这个; me.people=ko.array([ {“姓名”:“Irma Olsen”}, {“name”:“Winifred Cabrera”}, // ... {“姓名”:“卢修斯·霍华德”}, {“姓名
函数vm(){
“严格使用”;
var me=这个;
me.people=ko.array([
{“姓名”:“Irma Olsen”},
{“name”:“Winifred Cabrera”},
// ...
{“姓名”:“卢修斯·霍华德”},
{“姓名”:“赫达桑塔纳”}
]);
me.removePerson=函数(person){
我。人。移除(人);
};
me.animateOut=函数animateOut(节点、i、人){
//确保它不是文本节点
if(node.nodeType==node.ELEMENT\u node){
node.classList.add(“remove”);
}
}
}
应用绑定(新vm());
这是一个奇怪的问题,但我认为这与疯狂的浏览器渲染逻辑有关。你需要强制重画一张没有发生的照片。我们曾经:
<div class="person remove">
<div class="person">
然后我们去
<div class=person>
<div class=person>
同一个div不再有remove
类——当我们添加remove
类时,Knockout会删除数据,但是浏览器不知道更新这个div,因此它不会执行转换,这意味着transitionEnd
不会触发,div也不会被删除
那么我们如何强制重画呢?(一个有效的表达)
我相信有人可以更雄辩地解释这是如何工作的,以及为什么需要这样做,但至少它应该可以解决您眼前的问题。您的转换在
删除发生后结束,因此可能会弄乱渲染
您可以通过通知人员
集合转换已结束来修复此问题
me.animateOut = function animateOut(node, i, person) {
// Make sure it's not a text node
if (node.nodeType == Node.ELEMENT_NODE) {
node.addEventListener("transitionend", function () {
this.parentElement.removeChild(this);
me.people.notifySubscribers(); // Add this line here
});
node.classList.add("remove");
}
}
请注意,如果您有手动订阅,他们将收到通知回调的undefined
参数的通知,因此您应该做好准备。从beforeRemove
事件的中:
beforeRemove
-在删除数组项时调用,但
在删除相应的DOM节点之前。如果指定
在删除回调之前,那么您有责任删除回调
DOM节点。
在beforeRemove
中,仅当DOM节点不是文本节点时才删除它们,但需要删除所有节点
因此,您需要使用node.parentElement.removeChild(node)添加一个else
大小写代码>:
演示。疯狂的调用node.offsetHeight
修复了这个问题,我也不知道为什么这个黑客在这种情况下有效。谢谢,解决了这个问题。谢谢。可能最好也删除文本节点,但重画会解决问题。我认为正确的解决方案是删除文本节点,因为在这种情况下,knockout会正确处理渲染,而您不会强行重画…它确实有帮助,但是,在上一次转换仍在进行时删除项目时,仍然会出现此问题。强制重画是可行的。
<div class=person>
<div class=person>
me.animateOut = function animateOut(node, i, person) {
// Make sure it's not a text node
if (node.nodeType == Node.ELEMENT_NODE) {
node.addEventListener("transitionend", function () {
this.parentElement.removeChild(this);
me.people.notifySubscribers(); // Add this line here
});
node.classList.add("remove");
}
}
me.animateOut = function animateOut(node, i, person) {
// Make sure it's not a text node
if (node.nodeType == Node.ELEMENT_NODE) {
node.addEventListener("transitionend", function () {
this.parentElement.removeChild(this);
});
node.classList.add("remove");
}
else{
node.parentElement.removeChild(node);
}
}