如果不查询宽度属性,则转换不起作用

时间:2015-05-12 07:31:22

标签: javascript css3 css-transitions css-transforms

我想通过在js中为div添加一个类来为clickX设置转换动画。转换和转换属性将添加到css文件中。

var widget = document.getElementById('widget');    
widget.style.display = 'block';
document.getElementById('widget2').clientWidth; //comment this line out and it wont work
widget.className = 'visible';

只有在添加类之前我在dom中查询任何元素的width属性时才有效。

这是一个jsfiddle: https://jsfiddle.net/5z9fLsr5/2/

有谁可以解释为什么这不起作用?

2 个答案:

答案 0 :(得分:2)

那是因为你开始转换并同时修改了display属性“。改变display将破坏任何过渡(诚然需要引用),因此最好隔离display更改和实际过境:

https://jsfiddle.net/5z9fLsr5/3/

document.getElementById('showWidget').addEventListener('click', function(e) {
    e.preventDefault();
    var widget = document.getElementById('widget');    
    widget.style.display = 'block';
    //document.getElementById('widget2').clientWidth;
    window.setTimeout(function(){
        widget.className = 'visible';
    },0);
});
#widget {
    width: 200px;
    height: 80px;
    background: black;
    position: absolute;
    transition: transform 500ms;
    transform: translateX(-200px);
    display: none;
}
#widget.visible {
    transform: translateX(200px);
}



#widget2 {
    position: absolute;
    right: 0
}
<a href="#" id="showWidget">show</a>
<div id="widget"></div>
<div id="widget2">xxx</div>

查询clientWidth似乎暂停执行一段时间,所以它也有效。

答案 1 :(得分:0)

此处的问题是display: none的初始设置。对于浏览器的布局管理器,这表明应该完成布局,好像有问题的元素甚至不在DOM中(它仍然是,请注意)。这意味着不会应用CSS样式transform: translateX(-200px);

这样做:

widget.style.display = 'block';
widget.className = 'visible';

基本上同时触发两个修改 - 只在两个语句执行后才重新进行布局。插入document.getElementById('widget2').clientWidth;clientHeight也可以)会触发布局管理器进行重新绘制,从而注册transform: translateX(-200px)

正如其他人在我之前提到的那样,解决方案是使用opacity代替display(这是我的选择),或者使用延迟为0的setTimeout(见Why is setTimeout(fn, 0) sometimes useful?)。