Ric*_*ard 5 javascript css jquery
我有 2div秒,其中之一是通过display:none;. 两者在属性上都有相同的 css 过渡right。
如果我更改属性right通过jQuery和显示被隐藏的div,无论是使用$.css('display','none')或$.show()或$.toggle()等,隐藏DIV的结束位置瞬间画
$('button').on('click',function(){
$('.b').show();
$('.b').css('right','80%');
$('.a').css('right','80%');
})Run Code Online (Sandbox Code Playgroud)
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;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
如果我使用$.animate()它会起作用。但我的问题是;这是错误还是正常行为?
Kai*_*ido 10
要想看清情况,就需要了解 CSSOM 和 DOM 的关系。
在之前的 Q/A 中,我对重绘过程的工作原理有了一些了解。
基本上分为三个步骤,DOM 操作、回流和绘制。
CSS 转换通过从一种状态转换到另一种状态来工作。为此,他们查看元素的最后计算值以创建初始状态。
由于浏览器仅在需要时才重新计算计算出的样式,因此在过渡开始时,您应用的所有 DOM 操作均无效。
所以在你的第一个场景中,当计算转换的初始状态时,我们有
.b { computedStyle: {display: none} }
Run Code Online (Sandbox Code Playgroud)
......就是这样。
因为,是的,这display: none就是 CSSOM 的强大之处;如果一个元素有display: none,那么它不需要被绘制,它不存在。
所以我什至不确定转换算法是否会启动,但即使它启动,初始状态对于任何可转换值也是无效的,因为所有计算值都为空。
你的.a元素可见从一开始就没有这个问题,并且可以转变。
如果您能够使其延迟(由 引起$.animate)工作,那是因为在确实更改display属性的 DOM 操作与触发转换的延迟 DOM 操作的执行之间,浏览器确实触发了回流(例如,因为屏幕垂直同步在两者之间启动并且绘制操作被触发)。
现在,这不是问题的一部分,但既然我们确实更了解发生了什么,我们也可以更好地控制它。
事实上,一些 DOM 方法确实需要有最新的计算值。举例来说Element.getBoundingClientRect,或element.offsetHeight或getComputedStyle(element).height等等。所有这些需要整个页面已经更新,以便拳击正确做出的计算值(例如一个元素可以有一个保证金推或多或少等)。
这意味着我们不必知道浏览器何时会触发回流,我们可以强制它在我们想要的时候这样做。
但是请记住,页面上的所有元素都需要更新,这不是一个小操作,如果浏览器手头宽大,那是有充分理由的。
所以最好偶尔使用它,每帧最多使用一次。
幸运的是,Web API 使我们能够在此绘制操作发生之前挂钩一些 js 代码:requestAnimationFrame。
所以最好的办法是在这个 pre-paint 回调中只强制我们重排一次,并从这个回调中调用所有需要更新值的东西。
.b { computedStyle: {display: none} }
Run Code Online (Sandbox Code Playgroud)
$('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%');
});
})Run Code Online (Sandbox Code Playgroud)
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;
}Run Code Online (Sandbox Code Playgroud)
但说实话,设置起来并不总是那么容易,所以如果你确定它会偶尔被触发,你可能会很懒惰并同步进行:
<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>Run Code Online (Sandbox Code Playgroud)
$('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%');
})Run Code Online (Sandbox Code Playgroud)
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;
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2307 次 |
| 最近记录: |