gpt4 book ai didi

javascript - 如果元素开始隐藏,css 过渡不起作用

转载 作者:行者123 更新时间:2023-11-29 23:08:21 26 4
gpt4 key购买 nike

我有 2 div s,其中一个通过 display:none; 隐藏.两者在属性 right 上具有相同的 css 转换。 .

如果我更改属性 right通过 JQuery 并显示隐藏的 div , 通过使用 $.css('display','none')$.show()$.toggle()等等,隐藏的 div 立即在结束位置绘制

$('button').on('click',function(){
$('.b').show();
$('.b').css('right','80%');
$('.a').css('right','80%');
})
body {
width:800px;
height:800px;
}

div {
width:50px;
height:50px;
background-color:#333;
position:absolute;
display:none;
right:5%;
top:0;
transition:right .5s cubic-bezier(0.645, 0.045, 0.355, 1);
color: white;
}

.a {
display:block;
top:60px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='a'>A
</div>
<div class='b'>B
</div>
<button>Launch</button>


如果我使用 $.animate()它会起作用的。但我的问题是;这是错误还是正常行为?

编辑 不与 Transitions on the display: property 重复导致这里的问题不是动画显示属性也不是可见性

最佳答案

要清楚地理解这种情况,您需要了解 CSSOM 和 DOM 之间的关系。

previous Q/A ,我对重绘过程的工作原理进行了一些研究。
基本上,有三个步骤,DOM 操作、重排和绘制。

  • 第一个(DOM操作)只是修改一个js对象,并且都是同步的。
  • 第二个(reflow,又名布局)是我们感兴趣的,而且有点复杂,因为只有一些 DOM 方法和绘制操作需要它。它包括更新所有 CSS 规则并重新计算页面上每个元素的所有计算样式。
    作为一个相当复杂的操作,浏览器会尽可能少地尝试这样做。
  • 第三个(油漆)每秒最多只能完成 60 次(仅在需要时)。


  • CSS 转换通过从一种状态转换到另一种状态来工作。为此,他们会查看元素的最后计算值以创建初始状态。
    由于浏览器仅在需要时才重新计算计算样式,因此在过渡开始时,您应用的任何 DOM 操作都还没有生效。

    所以在你的第一个场景中,当计算转换的初始状态时,我们有
    .b { computedStyle: {display: none} }

    ……就是这样。

    因为,是的,这就是多么强大 display: none用于 CSSOM;如果一个元素有 display: none ,那么它就不需要画了,它不存在。

    所以我什至不确定转换算法是否会启动,但即使它启动了,初始状态对于 也是无效的。任意 可转换值,因为所有计算值都为空。

    您的 .a从一开始就可见的元素没有这个问题并且可以转换。

    而且,如果您能够使其延迟工作(由 $.animate 引起),那是因为在 DOM manip' 之间确实改变了 display属性和触发转换的延迟 DOM 操作的执行,浏览器确实触发了回流(例如,因为屏幕垂直同步在两者之间启动并且绘制操作被触发)。

    现在,这不是问题的一部分,但由于我们确实更好地了解发生了什么,我们也可以 更好地控制它 .

    确实, some DOM methods确实需要有最新的计算值。例如 Element.getBoundingClientRect , 或 element.offsetHeightgetComputedStyle(element).height等等。所有这些都需要 整页更新计算值,以便正确进行装箱(例如,一个元素可能有一个或多或少插入它的边距,等等)。

    这意味着我们不必不知道浏览器何时会触发此重排,我们可以在需要时强制它执行。

    但请记住, 页面上的所有元素需要更新,这不是一个小操作,如果浏览器宽松,这是有充分理由的。

    所以最好偶尔使用它,每帧最多一次。

    幸运的是,Web API 使我们能够在此绘制操作发生之前 Hook 一些 js 代码: requestAnimationFrame .

    所以最好的办法是在这个预绘制回调中只强制我们重排一次,并从这个回调中调用所有需要更新值的东西。

    $('button').on('click',function(){
    $('.b').show(); // apply display:block synchronously

    requestAnimationFrame(() => { // wait just before the next paint
    document.body.offsetHeight; // force a reflow
    // trigger the transitions
    $('.b').css('right','80%');
    $('.a').css('right','80%');
    });
    })
    body {
    width:800px;
    height:800px;
    }

    div {
    width:50px;
    height:50px;
    background-color:#333;
    position:absolute;
    display:none;
    right:5%;
    top:0;
    transition:right .5s cubic-bezier(0.645, 0.045, 0.355, 1);
    color: white;
    }

    .a {
    display:block;
    top:60px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class='a'>A
    </div>
    <div class='b'>B
    </div>
    <button>Launch</button>


    但老实说,设置起来并不总是那么容易,所以如果你确定它会偶尔被触发,你可能会很懒,并且同步进行:

    $('button').on('click',function(){
    $('.b').show(); // apply display:block
    document.body.offsetHeight; // force a reflow
    // trigger the transitions
    $('.b').css('right','80%');
    $('.a').css('right','80%');
    })
    body {
    width:800px;
    height:800px;
    }

    div {
    width:50px;
    height:50px;
    background-color:#333;
    position:absolute;
    display:none;
    right:5%;
    top:0;
    transition:right .5s cubic-bezier(0.645, 0.045, 0.355, 1);
    color: white;
    }

    .a {
    display:block;
    top:60px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class='a'>A
    </div>
    <div class='b'>B
    </div>
    <button>Launch</button>

    关于javascript - 如果元素开始隐藏,css 过渡不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54344996/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com