简体   繁体   English

为什么不应用CSS转换?

[英]Why doesn't CSS transition get applied?

I've built a small stacked bar visual just using floated divs that underneath is bound to some data using knockout . 我已经构建了一个小的堆叠条形视觉,只是使用浮动divs ,下面使用knockout绑定到一些数据。 What I want to be able to do is to animate changes in the size of these stacks when the data changes. 我希望能够做的是在数据更改时动画显示这些堆栈大小的变化。

I've managed to do this in the general case, so of the 4 bars that I've got, 3 of them transition correctly. 我已经设法在一般情况下做到了这一点,所以我已经有4个吧,其中3个正确转换。 The problem is my final bar seems to ignore the transition and instantly re-sizes and I can't understand why. 问题是我的最后一栏似乎忽略了过渡并立即重新调整大小,我无法理解为什么。 Here's a picture of the before/during/after states: 这是状态之前/期间/之后的图片:

在此输入图像描述

The way that I've defined this transition is simply via css 我定义这种转换的方式只是通过css

-webkit-transition: width 1s;
transition: width 1s;

The width of the bars is a computed value, calculating the percentage of items, so each bar should have it's width defined as a percentage. 条形的宽度是计算值,计算项目的百分比,因此每个条形的宽度应定义为百分比。 Although the red bar is calculated differently to the other 3 bars, I don't see why that should affect the transition. 虽然红色条的计算方式与其他3条不同,但我不明白为什么会影响过渡。

What I find quite strange, is that if I modify the width through the developer console for example, then the bar does correctly animate. 我觉得很奇怪,例如,如果我通过开发者控制台修改宽度,那么条形图就会正确生成动画。 I'm wondering if anyone can suggest why this might be the case? 我想知道是否有人可以建议为什么会出现这种情况?

 var vm = (function generateModel() { var data = { name: "Sign-off", id: "XX", values: [{ text: "Signed-off", count: 150, color: "#5fb5cc" }, { text: "Submitted", count: 90, color: "#75d181" }, { text: "Not Submitted", count: 75, color: "#f8a25b" } ], aggregates: { count: 650 } }; // Create a view model directly from the data which we will update var vm = ko.mapping.fromJS(data); // Add a computed value to calculate percentage vm.values().forEach(function (d) { d.percentage = ko.computed(function () { return d.count() / vm.aggregates.count() * 100; }); }); // Create a vm.allValues = ko.computed(function() { var values = []; var count = 0; var total = vm.aggregates.count(); debugger; // Add each of these results into those that will be returned vm.values().forEach(function(d) { values.push(d); count += d.count(); }); // Create an other category for everything else values.push({ text: ko.observable("Other"), count: ko.observable(total - count), percentage: ko.observable((total - count) / total * 100), color: ko.observable("#ff0000") }); return values; }); return vm; })(); ko.applyBindings(vm); setTimeout(function() { vm.values()[0].count(90); vm.values()[1].count(40); vm.values()[2].count(35); vm.aggregates.count(3550); }, 3000); 
 body { background: rgb(40, 40, 40); } .spacer { height: 230px; } .cards { float: right; } /* Small Card */ .card { margin-bottom: 3px; background: white; border-radius: 3px; width:398px; float: right; clear: both; min-height: 100px; padding: 10px 5px 15px 5px; font-family:'Open Sans', Arial, sans-serif; } .title { color: rgb(105, 161, 36); font-size: 16px; } .states { padding-top: 10px; } .state { font-size: 12px; color: rgb(67, 88, 98); padding: 0px 5px 2px 5px; clear: both; } .circle { width: 10px; height: 10px; border-radius: 50%; float: left; margin: 1px 5px 5px 0px; } .value { float: right; } .graph { padding: 10px 5px 0px 5px; } .bar { float: left; height: 10px; -webkit-transition: width 10s; transition: width 10s; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script> <div class="card"> <div class="content"> <div class="graph" data-bind="foreach: allValues"> <div class="bar" data-bind="style: { background: color, width: percentage() + '%' }"/> </div> </div> </div> 

As the first 3 are based on object references that don't change, knockout is preserving the actual <div> that's been rendered. 由于前3个基于不更改的对象引用,因此knockout保留了已呈现的实际<div>

For the final bar, each time allValues is evaluated, it's pushing a brand new object into the returned array. 对于最终的条形,每次评估allValues ,它都会将一个全新的对象推送到返回的数组中。 I would assume that since knockout sees that as a new object, it re-renders the div from scratch, rather than updating existing bindings. 我认为,因为knockout将其视为一个新对象,它会从头开始重新渲染div,而不是更新现有绑定。

You'll need to rework your model slightly to hold an actual object for that final value so that you can then update the observables on it in the same way. 您需要稍微修改模型以保存最终值的实际对象,以便您可以以相同的方式更新其上的可观察对象。

Here's a fixed version using a static object for the "other" value: 这是使用静态对象作为“其他”值的固定版本:

 var vm = (function generateModel() { var data = { name: "Sign-off", id: "XX", values: [{ text: "Signed-off", count: 150, color: "#5fb5cc" }, { text: "Submitted", count: 90, color: "#75d181" }, { text: "Not Submitted", count: 75, color: "#f8a25b" } ], aggregates: { count: 650 } }; // Create a view model directly from the data which we will update var vm = ko.mapping.fromJS(data); // Add a computed value to calculate percentage vm.values().forEach(function (d) { d.percentage = ko.computed(function () { return d.count() / vm.aggregates.count() * 100; }); }); //Create a static "others" object vm.other = { text: ko.observable("Other"), count: ko.computed(function() { var total = vm.aggregates.count(); var count = 0; vm.values().forEach(function(d) { count += d.count(); }); return total - count; }), percentage: ko.computed(function(d, b) { var total = vm.aggregates.count(); var count = 0; vm.values().forEach(function(d) { count += d.count(); }); return (total - count) / total * 100; }), color: ko.observable("#ff0000") }; // Create a vm.allValues = ko.computed(function() { var values = []; var count = 0; var total = vm.aggregates.count(); debugger; // Add each of these results into those that will be returned vm.values().forEach(function(d) { values.push(d); count += d.count(); }); // and push static object in instead of creating a new one values.push(vm.other); return values; }); return vm; })(); ko.applyBindings(vm); setTimeout(function() { vm.values()[0].count(90); vm.values()[1].count(40); vm.values()[2].count(35); vm.aggregates.count(3550); }, 3000); 
 body { background: rgb(40, 40, 40); } .spacer { height: 230px; } .cards { float: right; } /* Small Card */ .card { margin-bottom: 3px; background: white; border-radius: 3px; width:398px; float: right; clear: both; min-height: 100px; padding: 10px 5px 15px 5px; font-family:'Open Sans', Arial, sans-serif; } .title { color: rgb(105, 161, 36); font-size: 16px; } .states { padding-top: 10px; } .state { font-size: 12px; color: rgb(67, 88, 98); padding: 0px 5px 2px 5px; clear: both; } .circle { width: 10px; height: 10px; border-radius: 50%; float: left; margin: 1px 5px 5px 0px; } .value { float: right; } .graph { padding: 10px 5px 0px 5px; } .bar { float: left; height: 10px; -webkit-transition: width 10s; transition: width 10s; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script> <div class="card"> <div class="content"> <div class="graph" data-bind="foreach: allValues"> <div class="bar" data-bind="style: { background: color, width: percentage() + '%' }"/> </div> </div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM