修复:增加回到顶部功能,优化博客性能
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import { onPage } from "./lifecycle"
|
||||
|
||||
/**
|
||||
* 回到顶部按钮。
|
||||
*
|
||||
* 显隐**默认交给 CSS**:`animation-timeline: scroll(root block)` 让按钮随滚动位置
|
||||
* 淡入,不需要任何 scroll 监听(见 global.css 的 .back-to-top)。
|
||||
* 这里只负责两件事:
|
||||
* 1. 点击后平滑回到顶部;
|
||||
* 2. 给不支持滚动驱动动画的浏览器(Firefox < 144 / Safari < 26)做降级。
|
||||
*/
|
||||
|
||||
/** 与 global.css 里 animation-range 的起点保持一致 */
|
||||
const REVEAL_AFTER_PX = 480
|
||||
|
||||
const supportsScrollTimeline = () =>
|
||||
typeof CSS !== "undefined" &&
|
||||
typeof CSS.supports === "function" &&
|
||||
CSS.supports("animation-timeline: scroll()")
|
||||
|
||||
onPage("back-to-top", () => {
|
||||
const button = document.querySelector<HTMLElement>("[data-back-to-top]")
|
||||
if (!button) return
|
||||
|
||||
const onClick = () => {
|
||||
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
||||
window.scrollTo({ top: 0, behavior: reduceMotion ? "auto" : "smooth" })
|
||||
}
|
||||
button.addEventListener("click", onClick)
|
||||
|
||||
if (supportsScrollTimeline()) {
|
||||
return () => button.removeEventListener("click", onClick)
|
||||
}
|
||||
|
||||
// ——— 降级路径 ———
|
||||
// rAF 节流,且只在跨越阈值时才写 class:滚动本身不产生布局读取(只用 scrollY)
|
||||
const root = document.documentElement
|
||||
root.classList.add("no-scroll-timeline")
|
||||
|
||||
let frame = 0
|
||||
const update = () => {
|
||||
frame = 0
|
||||
button.classList.toggle("is-visible", window.scrollY > REVEAL_AFTER_PX)
|
||||
}
|
||||
const onScroll = () => {
|
||||
if (frame) return
|
||||
frame = window.requestAnimationFrame(update)
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", onScroll, { passive: true })
|
||||
update()
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("scroll", onScroll)
|
||||
if (frame) window.cancelAnimationFrame(frame)
|
||||
button.removeEventListener("click", onClick)
|
||||
root.classList.remove("no-scroll-timeline")
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user