在一个长内容的页面中,当滚动到一定的距离时,会出现一个 "返回顶部" 的图标,点击会平滑的返回到页面顶部,有助于提升用户体验
页面内平滑滚动
-
使用 a 标签锚点定位
<nav> <a href="#hat">点位一</a> <a href="#shoes">点位二</a> <a href="#clothes">点位三</a> </nav> <section id="hat">内容一</section> <section id="shoes">内容二</section> <section id="clothes">内容三</section>给根元素添加滚动行为属性,实现锚点定位平滑滚动效果
html { scroll-behavior: smooth; }注意:在使用上依赖于 a 标签的 href 属性,不仅有局限性,还会污染页面路径,如果页面路径中包含有参数,则不推荐使用
-
使用 Element 的 scrollIntoView 方法
<ul id="navigation"> <li data-anchor="hat">点位一</li> <li data-anchor="shoes">点位二</li> <li data-anchor="clothes">点位三</li> </ul> <section id="hat">内容一</section> <section id="shoes">内容二</section> <section id="clothes">内容三</section>const navigation = document.querySelector('#navigation') navigation.addEventListener('click', event => { const anchor = event.target.dataset.anchor // 可能不会完全滚动到顶端或底端,这取决于其它元素的布局情况 anchor.scrollIntoView({ behavior: 'smooth', block: 'end' }) })总结:弥补了 a 标签锚点定位的不足,既可以应用到任何元素,也不影响页面路径
-
滚动到指定元素区域
const smoothScroll = selector => { document .querySelector(selector.startsWith('#') ? selector : `#${selector}`) .scrollIntoView({ behavior: 'smooth' }) } -
重复地滚动某个距离(距离叠加)
window.scrollBy({ top: window.innerHeight, behavior: 'smooth' })
返回顶部(JS版本)
-
HTML基本结构
<div class="backtop">TOP</div> -
CSS布局技巧
.backtop { position: fixed; bottom: 30px; right: 25px; background-color: rgba(0, 0, 0, .45); opacity: 0; visibility: hidden; transition: all .25s; } .backtop:hover { opacity: .8; cursor: pointer; } .backtop.fade { opacity: 1; visibility: visible; }将
opacity和visibility结合使用实现淡入淡出效果 -
事件绑定逻辑
const el = document.querySelector('.backtop') el.addEventListener('click', () => { window.scroll({ top: 0, behavior: 'smooth' }) }) window.addEventListener('scroll', () => { const { scrollTop } = document.documentElement || document.body if (scrollTop > 200 && !el.classList.contains('fade')) { el.classList.add('fade') } if (scrollTop < 200 && el.classList.contains('fade')) { el.classList.remove('fade') } })注意:由于
scroll事件高频触发,在性能上会有一定的影响 -
使用防抖优化 scroll 事件
const debounce = (func, wait = 350) => { let timer = null return () => { timer && clearTimeout(timer) timer = setTimeout(() => { func.apply(this, null) }, wait) } }无论调用多少次,都在操作 350ms 后执行最后一次,以此来降低执行频率且不影响效果
返回顶部(CSS版本)
-
平滑滚动到顶部
<a href="#" class="backtop"></a>html { scroll-behavior: smooth; }使用锚点定位和根元素的滚动行为属性实现,上边我们提到这种方式会污染页面路径
-
返回图标的位置
.backtop { position: sticky; top: -115px; right: 15px; float: right; width: 50px; height: 50px; border-radius: 50%; transform: translateY(calc(100vh + 50px)); background: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1812 1024' xmlns='http://www.w3.org/2000/svg' width='353.906' height='200'%3E%3Cpath d='M889.849 273.684L194.723 968.809c-44.462 44.462-116.654 44.455-161.186-.076-44.841-44.842-44.565-116.697-.076-161.186L807.674 33.334c44.461-44.462 116.654-44.455 161.185.077a117.133 117.133 0 0 1 5.942 6.4 114.147 114.147 0 0 1 19.08 15.38l774.212 774.212c44.49 44.49 44.766 116.344-.076 161.186-44.532 44.532-116.724 44.539-161.186.077L889.849 273.684z' fill='%23fff'/%3E%3C/svg%3E") center no-repeat #1e90ff; background-size: 50%; }
本期总结
经过以上分析,我们可以把两种实现方式结合一下,点击返回平滑滚动使用 JS 来实现,图标的位置使用 CSS 来实现,这样既不污染页面路径又避免了高频的 scroll 事件
通过 smooth scroll behavior polyfill 解决平滑滚动的兼容性问题
一起学习,加群交流看 沸点