在我的項(xiàng)目中,當(dāng)用戶(hù)單擊按鈕時(shí),我一直在使用 jQuery slideUp()
向上滑動(dòng) 200 項(xiàng)列表中的元素。但是,眾所周知,CSS 高度動(dòng)畫(huà)需要回流,從而導(dǎo)致動(dòng)畫(huà)不穩(wěn)定。該動(dòng)畫(huà)是應(yīng)用程序的一個(gè)組成部分,我愿意做大量的工作以使其工作并順利工作。
我決定 CSS transform
是讓它順利工作的方法,因?yàn)樗窃?GPU 上處理的,在一些現(xiàn)代瀏覽器上,它甚至脫離了主線程,繁重的 JS 工作不會(huì)影響變換。 (我確實(shí)有繁重的 JS 工作)。
我正在尋找一個(gè)使用CSS transition的巧妙解決方案:transform
來(lái)復(fù)制jQuery slideUp
,它只是為height
屬性設(shè)置動(dòng)畫(huà)。以下是我的嘗試,但似乎 scale
和 translate
未按預(yù)期同步。
$("button").on("click", function() { $(".collapsible").addClass("collapsed") setTimeout(function() { $(".collapsible").removeClass("collapsed") }, 5000); });
.list-item { width: 400px; height: 100px; background-color: blue; margin-top: 10px; overflow-y: hidden; } .collapsible.collapsed .content { transition: transform 3s linear; transform: scale(1, 1) translate(0, -100%); } .collapsible.collapsed { transition: transform 3s linear; transform: translate(0, -50%) scale(1, 0); } .collapsible.collapsed ~ .list-item { transition: transform 3s linear; transform: translate(0, -100%); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script> <button>Collapse</button> <div class="list-item collapsible"> <div class="content"> Just an example <br> Just an example <br> Just an example <br> Just an example <br> Just an example <br> </div> </div> <div class="list-item"> </div> <div class="list-item"> </div>
我對(duì)這些值進(jìn)行了一些修改,并通過(guò)將 content
轉(zhuǎn)換更改為 transform:scale(1, 3) translate(0, -50%);
來(lái)使其更接近。
看來(lái)我已經(jīng)非常接近實(shí)現(xiàn)目標(biāo),但從未完全成功。有什么現(xiàn)成的技巧可以做到這一點(diǎn)嗎?
要求:
經(jīng)過(guò)幾個(gè)晚上的睡眠,我找到了一個(gè)完全符合我需要的解決方案。我必須使用三層 div
并確保內(nèi)部?jī)蓪釉O(shè)置為 height: 100%;
。然后,我取消了 scale()
并使用 transform()
將中間層向上滑動(dòng)。
這符合我的要求:
Transform()
,其在 GPU 上的運(yùn)行速度應(yīng)高達(dá) 60fpsScale()
壓縮內(nèi)容SlideUp()
$("button").on("click", function() { const height = $(".collapsible").css("height"); $(":root").css("--height", height); $(".collapsible").addClass("collapsed"); setTimeout(function() { $(".collapsible").removeClass("collapsed"); }, 4000); });
:root { --height: unset; } .outer-container { width: 400px; height: fit-content; background-color: transparent; margin-top: 10px; overflow-y: hidden; } .inner-container { height: 100%; background-color: blue; overflow: hidden; } .content { height: 100%; } .collapsible.collapsed .inner-container { transition: transform 3s linear; transform: translate(0, -100%); } .collapsible.collapsed .content { transition: transform 3s linear; transform: translate(0, 100%); } .collapsible.collapsed ~ .outer-container { transition: transform 3s linear; transform: translate(0, calc((var(--height) * -1) - 10px)); } .collapsible .inner-container { transition: transform .5s ease-in-out; transform: translate(0, 0); } .collapsible .content { transition: transform .5s ease-in-out; transform: translate(0, 0); } .collapsible ~ .outer-container { transition: transform .5s ease-in-out; transform: translate(0, 0); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script> <button>Collapse</button> <div class="outer-container"> <div class="inner-container"> <div class="content"> Just an example <br> Just an example <br> Just an example <br> Just an example <br> </div> </div> </div> <div class="outer-container collapsible"> <div class="inner-container"> <div class="content"> Just an example <br> Just an example <br> Just an example <br> Just an example <br> Just an example <br> </div> </div> </div> <div class="outer-container"> <div class="inner-container"> <div class="content"> Just an example <br> Just an example <br> Just an example <br> </div> </div> </div> <div class="outer-container"> <div class="inner-container"> <div class="content"> Just an example <br> Just an example <br> Just an example <br> Just an example <br> </div> </div> </div>