scrollIntoView 與 scrollIntoViewIfNeeded API 介紹

sea_ljf發表於2017-10-06

Hello~親愛的觀眾老爺們大家好!國慶中秋長假快放完了,是時候收拾心(ti)情(zhong)好好學習與工作啦。這次為大家帶來的是兩個好用 API 的介紹,其實也是偷懶神器。

根據 MDN的描述,Element.scrollIntoView()方法讓當前的元素滾動到瀏覽器視窗的可視區域內。

Element.scrollIntoViewIfNeeded()方法也是用來將不在瀏覽器視窗的可見區域內的元素滾動到瀏覽器視窗的可見區域。但如果該元素已經在瀏覽器視窗的可見區域內,則不會發生滾動。此方法是標準的Element.scrollIntoView()方法的專有變體。

因而再有什麼回到頂部、去到置頂位置和鍵盤彈出擋住輸入框之類的需求,都可以簡單解決了。

然而,面對好用的 API,前端們第一個反映都是,看相容性!

先看scrollIntoView的:

看到一片黃黃綠綠的,基本可以安心,不支援的只是某個屬性的取值而已,下面會有介紹~

之後看看scrollIntoViewIfNeeded

IEFireFox全紅,如果PC端想用的話,基本只能內部專案了,略為可惜。但移動端還是綠悠悠的,基本都OK,可以安心使用~

由於本文是介紹向~因而每個屬性我都寫了點小demo,點進去就可以體驗一下哦!

scrollIntoView

先介紹scrollIntoView,使用起來其實很簡單,獲取某個元素後,直接呼叫scrollIntoViewIfNeeded()即可,簡單的demo點這就好,點一下側邊的小綠塊,頁面就會滾上去。demo程式碼大概長這樣:

<body>
    <div class="chunk"></div>
    <div class="btn">click</div>
    <script>
    const btn = document.querySelector('.btn');
    const test = document.querySelector('.chunk');
    btn.addEventListener('click', function() {
      test.scrollIntoView();
    })
    </script>
</body>複製程式碼

是不是很簡單~不過可能有同學就有疑問了,這不就和錨點定位一樣嗎?感覺毫無意義啊!先別急,當你呼叫scrollIntoView的時候,其實是可以傳引數進去的。scrollIntoView只接受一個引數,但接受兩種型別的引數,分別是Boolean型引數和Object型引數。

先說Boolean型引數,顧名思義,引數可以使truefalse。如果為true,元素的頂端將和其所在滾動區的可視區域的頂端對齊。若為false,元素的底端將和其所在滾動區的可視區域的底端對齊。簡單的例子可以點這裡。主要程式碼如下:

<body>
    <div class="chunk"></div>
    <div class="btn-top">up</div>
    <div class="btn-bottom">down</div>
    <script>
    const up = document.querySelector('.btn-top');
    const down = document.querySelector('.btn-bottom');
    const test = document.querySelector('.chunk');
    up.addEventListener('click', function() {
      test.scrollIntoView(true);
    });
    down.addEventListener('click', function() {
      test.scrollIntoView(false);
    });
    </script>
</body>複製程式碼

如你所見到的,當傳入引數為分別為truefalse時,當點選右側的按鈕時,紅色的div會貼近可視區域的頂部或底部。

之後是Object型引數,這個物件有兩個選項,也就是物件裡面的keyblock與之前的Boolean型引數一致,不過值不再是truefalse,是更語義化的startend

另一個選項是behavior,MDN上給出三個可取的值,分別是autoinstantsmooth。這個選項決定頁面是如何滾動的,實測autoinstant都是瞬間跳到相應的位置,查閱W3C後發現了這麼一句:"The instant value of scroll-behavior was renamed to auto."。因而基本可以確定兩者表現是一致的。而smooth就是有動畫的過程,可惜的是之前提及相容性時說過,黃色其實不支援某個屬性,就是不支援behavior取值為smooth。而且,實測了IE及移動端的UC瀏覽器後發現,它們根本就不支援Object型引數,因而在呼叫scrollIntoView({...})時,只有預設的結果,即scrollIntoView(true)。簡單的例子看這裡,如果想體驗smooth的效果,需要使用Chrome或者Firefox哦!主要程式碼如下:

<body>
    <div class="chunk"></div>
    <div class="btn-top">up</div>
    <div class="btn-bottom">down</div>
    <script>
    const up = document.querySelector('.btn-top');
    const down = document.querySelector('.btn-bottom');
    const test = document.querySelector('.chunk');
    up.addEventListener('click', function() {
      test.scrollIntoView({
        block: 'start',
        behavior: 'smooth'
      });
    });
    down.addEventListener('click', function() {
      test.scrollIntoView({
        block: 'end',
        behavior: 'smooth'
      });
    });
    </script>
</body>複製程式碼

scrollIntoViewIfNeeded

介紹完scrollIntoView,是時候介紹一下它的變體scrollIntoViewIfNeeded了。兩者主要區別有兩個。首先是scrollIntoViewIfNeeded是比較懶散的,如果元素在可視區域,那麼呼叫它的時候,頁面是不會發生滾動的。其次是scrollIntoViewIfNeeded只有Boolean型引數,也就是說,都是瞬間滾動,沒有動畫的可能了。

scrollIntoViewIfNeeded可以接受一個Boolean型引數,和scrollIntoView不同,true為預設值,但不是滾動到頂部,而是讓元素在可視區域中居中對齊;false時元素可能頂部或底部對齊,視乎元素靠哪邊更近。簡單的例子可以點這裡。大致程式碼如下:

<body>
    <div class="chunk"></div>
    <div class="scrollIntoView">scrollIntoView top</div>
    <div class="scrollIntoViewIfNeeded-top">scrollIntoViewIfNeeded top</div>
    <div class="scrollIntoViewIfNeeded-bottom">scrollIntoViewIfNeeded botom</div>
    <script>
    const scrollIntoView = document.querySelector('.scrollIntoView');
    const scrollIntoViewIfNeededTop = document.querySelector('.scrollIntoViewIfNeeded-top');
    const scrollIntoViewIfNeededBottom = document.querySelector('.scrollIntoViewIfNeeded-bottom');
    const test = document.querySelector('.chunk');
    scrollIntoView.addEventListener('click', function() {
      test.scrollIntoView(true);
    });
    scrollIntoViewIfNeededTop.addEventListener('click', function() {
      test.scrollIntoViewIfNeeded(true);
    });
    scrollIntoViewIfNeededBottom.addEventListener('click', function() {
      test.scrollIntoViewIfNeeded(false);
    });
    </script>
</body>複製程式碼

如文件所說,當紅色的div完全在可視區域的情況下,呼叫scrollIntoView()是會發生滾動,而呼叫scrollIntoViewIfNeeded()則不會。而我實踐後發現了一些文件沒有的細節。當元素處於可視區域,但不是全部可見的情況下,呼叫scrollIntoViewIfNeeded()時,無論引數是true還是false,都會發生滾動,而且效果是滾動到元素與可視區域頂部或底部對齊,視乎元素離哪端更近。這個大家需要注意一下~

小結

其實這個API並不是必須的,有很多其他方法可以達到它的效果。然而在條件許可的情況下,使用一下是能節省下好多的JS程式碼或是一堆錨點,還是很爽的。

感謝各位看官大人看到這裡~希望本文對你有所幫助,記得使用一下這兩個API哦!

相關文章