<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一行代碼實現(xiàn)display"過渡動畫"原理

          共 2420字,需瀏覽 5分鐘

           ·

          2020-09-22 16:37

          寫本文的起因

          • 上篇文章,提到如何讓display出現(xiàn)過渡動畫,卻沒有仔細介紹原理。
          • 為了更好的讓想學習的人深入理解于是加班加點寫下了這篇“短文”,我想以后還是以短文為主,不然大家看起來太累

          正式開始

          • 初始化界面


          "en">


          ????"UTF-8">
          ????"viewport"?content="width=device-width,?initial-scale=1.0">
          ????Document
          ????



          ????"app">
          ????

          ????"test">測試



          • 此時我將app的display初始化為none,并且寫入腳本文件

          ????。。。

          • 初始化界面變成了這樣:
          • 此時,我點擊測試按鈕
          • 并沒有出現(xiàn)動畫,非常生硬的出來了,有一些場景我又要性能,比如初始化不渲染,但是當它出現(xiàn)又要有動畫的時候,就有可能使用這行代碼

          ?test.onclick?=?function?()?{
          ????????const?app?=?document.querySelector('#app')
          ????????console.log(app,?'app')
          ????????app.style.display?=?"block"
          ????????const?height?=?app.offsetHeight
          ????????app.style.transform?=?"translateX(200px)"
          ????}
          • 當我加入const height = app.offsetHeight這行代碼的時候,再點擊測試按鈕,display切換就順帶出來了“動畫”,有了過度效果
          • 為什么會出現(xiàn)動畫了呢?因為我讀取dom的這些特殊屬性時,瀏覽器就會強制清空渲染隊列一次,讓我拿到最新的值。也就是說讀取的時候,其實已經(jīng)是display為"block"了,因此。我們出現(xiàn)了過渡動畫

          效果如下所示:


          出現(xiàn)“過渡動畫”是什么情況?

          • 其實display是不能出現(xiàn)動畫的,所以標題+了引號
          • 怎么才能有過渡?
            • 有數(shù)字的變化,例如透明度,從0-1.
            • 初始化有渲染展示的
            • transition里面包含的屬性
            • ...等 大家可以補充

          為什么加了一行代碼后,就能出現(xiàn)動畫了?

          • 大家在寫現(xiàn)代前端框架,遇到最多的問題就是渲染的時期不確定的問題。
            • 例如vue里面的nextTick實現(xiàn),有一個優(yōu)雅降級的實現(xiàn)。它在mounted生命周期函數(shù)里面去獲取dom節(jié)點時候,經(jīng)常獲取不到或者獲取不到完整渲染的dom節(jié)點。(我很久沒有使用vue了,有問題可以補充),為什么?
            • 像現(xiàn)在數(shù)據(jù)驅動的框架,只要數(shù)據(jù)改變了,對應邏輯綁定了數(shù)據(jù)的dom節(jié)點按道理應該更新,可是更新時機是我們無法確定的,因為這中間有中間層,比如存在diff算法計算過程,可能存在隊列,因為當你頻繁修改數(shù)據(jù)的時候,框架本身要做優(yōu)化,合并一段時間的數(shù)據(jù)更新再去真正更新dom,等這些事情都做完了,才能去更新dom節(jié)點,然后我們才能看到最新數(shù)據(jù)對應的節(jié)點
            • 當我們真的要去更新dom節(jié)點的時候,也存在一個隊列。這個就是瀏覽器的渲染隊列
          • 如果你無法理解我上面說的,可以看我之前手寫React系列文章中的setState異步隊列實現(xiàn)

          瀏覽器的渲染隊列

          • 什么時候最能體現(xiàn)這個隊列的作用?
            • 頻繁直接操作dom時候,例如for循環(huán)里面頻繁操作dom,這個時候瀏覽器就會優(yōu)化我們的操作,合并一部分操作一次性執(zhí)行
            • 渲染隊列跟display的關聯(lián)

          • 當我們執(zhí)行了app.style.display = "block"這行代碼時候,dom節(jié)點此時并沒有更新,js解析引擎是聰明的,它發(fā)現(xiàn)你后面馬上有代碼要修改dom節(jié)點,會先存入隊列中集中一次性操作
          • 當我們執(zhí)行了app.offsetHeight這行代碼時候,發(fā)現(xiàn)我們需要讀取dom節(jié)點的屬性,瀏覽器害怕現(xiàn)在隊列中沒有執(zhí)行的操作會讓你讀取到不正確的值引發(fā)BUG,于是就會清空渲染隊列并且執(zhí)行,讓你拿到最精確/新的

          • 當你請求向瀏覽器請求一些 style信息的時候,就會讓瀏覽器flush隊列,比如:
            • offsetTop, offsetLeft, offsetWidth, offsetHeight
            • scrollTop/Left/Width/Height
            • clientTop/Left/Width/Height
            • width,height
          • 當你請求上面的一些屬性的時候,瀏覽器為了給你最精確的值,需要flush隊列,
          • 因為隊列中可能會有影響到這些值的操作。即使你獲取元素的布局和樣式信息跟最近發(fā)生或改變的布局信息無關,
          • 瀏覽器都會強行刷新渲染隊列。

          清空渲染隊列后

          • 當讀取offsetHeight屬性后,我們清空了渲染隊列,那么此時dom重新渲染完成后,此時display已經(jīng)是block了。而且展示在界面上面了,我們再操作dom屬性就會出現(xiàn)過渡動畫了。

          最后

          • 紙上得來終覺淺,多實踐、多思考是走向更高級別必經(jīng)之路,想要看我之前手寫源碼文章的,我的gitHub源碼地址是:https://github.com/JinJieTan/Peter-,記得Star

          • 掃碼關注公眾號,訂閱更多精彩內容。


            “在看和轉發(fā)”就是最大的支持
          瀏覽 37
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天干在线观看 | 操你小骚逼 | 国产激情综合AV | 91性爱视频在线观看 | 亚洲高清一区无码 |