【问题标题】:Transition not working without querying width property在不查询宽度属性的情况下转换不起作用
【发布时间】:2015-07-22 22:47:31
【问题描述】:

我想通过在 js 中的 div 中添加一个类来为一个带有转换的 translateX 设置动画。在 css 文件中添加了 transform 和 transition 属性。

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 中 any 元素的 width 属性时才有效。

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

谁能解释为什么这不起作用?

【问题讨论】:

标签: javascript css css-transitions css-transforms


【解决方案1】:

这里的问题是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?)。

【讨论】:

    【解决方案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 似乎会“暂停”执行一段时间,所以它也可以。

    【讨论】:

    • 没有意识到 display 道具对我的动画有如此大的影响。感谢您的快速响应。我还想到了通过查询宽度来触发某种布局
    • @yacon 因为display 不是“可迁移的”,所以任何涉及display 的转换(即使您明确定义transition-property 以排除它)都会失败。
    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 2018-08-22
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    相关资源
    最近更新 更多