回到页面顶部、兼容性、最佳写法、滚动到任意处javascript
在 你们一块儿被捕吧 中刚写了:css
在平常开发中咱们每每会从用户那得到各类输入,例如搜索框、评论框、文章内容等等。html
结果在 segmentfault
阅读评论时看到了一个连接一点直接把我给滚动到顶部
,顿时心中一阵 惨叫双手捶胸
后把页面拉回评论并打开了 控制台
查看了连接为什么方神圣:java
<a href="#">...</a>
复制代码
顿时又是一阵 惨叫双手捶胸
原来 segmentfault
评论是支持 markdown 语法的,若是再评论里输入 [...](#)
则会被转换成如上代码。git
好奇心突发跑到了 掘金
测试了一下带链接的评论,打开 控制台
看了看因为使用了 target="_blank"
没有出现被传送到顶部的状况,内心暗暗道 喵哉 🐱
之后仍是得当心行事,碰巧每日30秒正愁不知道写什么那就来写写 回到顶部
吧。github
第一种写法就介绍一下今天被中全套的代码,利用了 锚点
来实现回到顶部:segmentfault
<a href="#"回顶部></a>
复制代码
若是须要滚动到别的元素可使用 id
属性配合 锚点
来实现:浏览器
<header id="header">我是头部</header>
<a href="#header">回到页面头部</a>
复制代码
不过因为这种方法 滚动
得太快了,性能确定是很好就是体验不怎么好。不过咱们可使用 css 的 scroll-behavior
属性来提高体验:微信
html, body {
scroll-behavior: smooth;
}
复制代码
虽然第一种方法配合 css 的 scroll-behavior
属性显得挺不错,可是 scroll-behavior
兼容性挺不高的具体能够看 caniuse。markdown
因为在页面垂直滚动过程当中会改变 window.scrollY
的值,第二种即是写法利用 window.scrollTo()
把它设置为 0
来实现回到顶部:
window.scrollTo(0, 0)
复制代码
不过这样使用也会致使 滚动
得太快带来的体验很差,这个时候咱们能够利用 window.requestAnimationFrame()
告诉浏览器——你但愿执行一个动画,而且要求浏览器在下次重绘以前调用指定的回调函数更新动画,该方法须要传入一个回调函数做为参数,该回调函数会在浏览器下一次重绘以前执行。
这里使用里一个来判断当页面没有滚动到顶部时循环调用 window.requestAnimationFrame
来进行逐步滚动,每次滚动的距离 c - c / 8
随着 c
的减少而减少进而实现滚动效果:
const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};
复制代码
不过继续查阅 caniuse 中的 window.requestAnimationFrame()
在主流浏览器中支持挺好的,可是须要兼容 ie6-9
的同窗就得另外寻找方法了。仔细想一想 window.requestAnimationFrame()
跟 setTimeout()
好像有点类似。
window.requestAnimationFrame
回调函数执行次数一般是每秒60次即一秒60帧,将 setTimeout
执行的频率也设置为同样的就好了:
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (callback) {
return setTimeout(callback, 1000 / 60);
}
}
const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};
复制代码
搞定神器 ie6-9
的兼容问题。
第三种写法使用函数 Element.scrollIntoView()
能够将选中的元素移动到 可视区域
,可视区域
更多相关知识点能够看以前的一篇文章 巧用可视区域。
document.querySelector('body')
.scrollIntoView({
behavior: 'smooth',
block: 'start',
})
复制代码
代码实现比起第三种简单了很多,当 css 的 scroll-behavior
被设置时会默认设置 Element.scrollIntoView()
的 behavior
,依旧打开 caniuse 查看兼容性会发现和 window.requestAnimationFrame()
比起来差不了多少,在神器 ie6-9
也有兼容问题。
第四种方法将前面方法进行一个整合,页面支持 Element.scrollIntoView()
则直接使用第三种方法,若是页面不支持则使用第二种方法。对于 Element.scrollIntoView()
的支持利用到了 window.getComputedStyle()
也有兼容性问题须要判断一下:
let scrollToTop;
if (window.getComputedStyle && window.getComputedStyle(document.body).scrollBehavior) {
scrollToTop = () => document.querySelector('body')
.scrollIntoView({
behavior: 'smooth',
block: 'start',
});
} else {
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (callback) {
return setTimeout(callback, 1000 / 60);
}
}
scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};
}
复制代码
在开发中要注意浏览器的兼容性,多使用 caniuse
来帮助咱们参看兼容性状况。并根据产品的开发需求来书写代码,例如不须要兼容 ie6-9
时咱们能够直接使用 Element.scrollIntoView()
。在刚才的学习中除了学习了回到顶部外,只需再学习一下获取元素所在 y
轴坐标或者高度就会 一不当心顺手
学习了滚动到页面各处。
在困惑的城市里总少不了并肩同行的
伙伴
让咱们一块儿成长。
点赞
。小星星
。m353839115
。本文原稿来自 PushMeTop