眾所皆知 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
而不是behaviour
htm
這個方式很是方便不過目前只有 Firefox 支援,查閱 Can I Use。ip
然後是 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。