[譯] scroll-behavior 滑順的捲動效果

眾所皆知 HTML 錨點(anchor link)透過給定標籤 id 屬性跳到頁面上特定位置的功能。不過這個效果感覺上就像是閃一下就切換到該位置。
為了使用體驗上的感覺有時候網站會設計一種平滑捲動到該位置的效果。css

在過去這樣的效果一般會透過 jQuery 來達成,但有時候一些簡單的頁面為了達成這個功能就須要載入一堆函式庫或框架這未免有點矯枉過正。
最新的 Javascript 提供了一個更有效率,加強原生 window.scrollTo 的方式。html

一個標準的錨點已經是一個被廣泛使用的基本技巧: 透過這種方式就算新的 smooth scroll 滑順捲動的語法不被支援就的方法仍然會運做,就是跳到該位置。app

<a href="#dest">Click to somewhere</a>
...
<p id="dest">This is the target</p>

要注意的是頁面內容要超過可視區域就是至少 scroll bar 要出現,若是瀏覽器已經在畫面上顯示出兩者且沒得捲就沒有效果。所以我們須要在連結和錨點之間補上一些內容。框架

兩種方式

由於 Smooth Scrolling API 有兩種,一種是 CSS, 一種則是 Javascript。也所以形成混亂的緣由是部分瀏覽器有支援上不一致。code

CSS 的方式很是簡單,只要在該元素設定 scroll-behavior: smooth;router

body {
  scroll-behavior: smooth;
}

注意是 behavior 而不是 behaviourhtm

這個方式很是方便不過目前只有 Firefox 支援,查閱 Can I Useip

Javascript

然後是 Javascript 的方式get

var anchor = document.querySelector('a[href="#dest"]')
var target = document.getElementById('dest')
anchor.addEventListener('click', function (e) {
  if (window.scrollTo) {
    e.preventDefault()
    window.scrollTo({'behavior': 'smooth', 'top': target.offsetTop})
  }
})

注意到 window.scrollTo 跟現有的 Javascript 在參數上有些不一樣,若是你直接用在 Chrome 下,您就會出現參數數量不對的錯誤,因此實務上要應用還是須要額外作些處理。string

另外這種方式有一個缺點,那就是我們不能自訂 timing function

延伸

上面的 script 已經能夠讓單一的錨點正常的運做,不過這種方式有點面對大量連結的時候有點麻煩。假如我們在這個頁面有幾個錨點都要這功能,那麼我們能夠簡單的實做以下。

var applyScrolling = function (arr, cb) {
  for (var i = 0; i < arr.length; i++) {
    cb.call(null, i, arr[i])
  }
}

// 注意若是有使用 router 那麼自訂一個 class 能夠避免一些問題
var anchors = document.querySelectorAll("a[href^='#']")
if (window.scrollTo) {
  applyScrolling(anchors, function (index, el) {
    var target = document.getElementById(el.getAttribute('href').substring(1))

    el.addEventListener('click', function (e) {
      console.log(target)
      e.preventDefault()
      // 這邊跟新的 method 參數是不一樣的。
      window.scrollTo(0, target.offsetTop)
    })
  })
}

譯者小結

目前在 Firefox 下兩種方式均可以使用,而 Chrome 則須要額外的開啟設定。本文就是先記錄一下這些新的屬性與 API。

參考

相關文章
相關標籤/搜索