为什么不应用CSS转换? [英] Why doesn't CSS transition get applied?

查看:49
本文介绍了为什么不应用CSS转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用浮动的 divs 构建了一个小的堆叠条形图,其下面使用 knockout 。我希望能够做的是在数据发生变化时动画显示这些堆栈大小的变化。

I've built a small stacked bar visual just using floated divs that underneath is bound to some data using knockout. What I want to be able to do is to animate changes in the size of these stacks when the data changes.

我在一般情况下设法做到了这一点,我所拥有的4个酒吧,其中3个正确过渡。问题是我的最后一栏似乎忽略了过渡并立即重新调整大小,我无法理解为什么。这是状态之前/期间/之后的图片:

I've managed to do this in the general case, so of the 4 bars that I've got, 3 of them transition correctly. 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:

我定义此转换的方式只是通过css

The way that I've defined this transition is simply via css

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

条形的宽度是一个计算值,计算项目的百分比,所以每个条形应该有它的宽度定义为百分比。虽然红色条的计算方式与其他3条不同,但我不明白为什么会影响过渡。

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.

我觉得很奇怪,如果我例如,通过开发者控制台修改宽度,然后条形图正确设置动画。我想知道是否有人可以建议为什么会出现这种情况?

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>

推荐答案

由于前3个基于不改变的对象引用,因此knockout保留了已呈现的实际< div>

As the first 3 are based on object references that don't change, knockout is preserving the actual <div> that's been rendered.

对于最后一个栏,每次 allValues 被评估时,它会将一个全新的对象推送到返回的数组中。我认为,因为knockout将其视为一个新对象,它会从头开始重新渲染div,而不是更新现有绑定。

For the final bar, each time allValues is evaluated, it's pushing a brand new object into the returned array. I would assume that since knockout sees that as a new object, it re-renders the div from scratch, rather than updating existing bindings.

你需要重做你的稍微建模以保存该最终值的实际对象,以便您可以以相同的方式更新其上的observable。

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>

这篇关于为什么不应用CSS转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆