每日 30 秒 ⏱ 迴囬囘回到顶部

简介

回到页面顶部、兼容性、最佳写法、滚动到任意处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 兼容性挺不高的具体能够看 caniusemarkdown

迴到顶部

因为在页面垂直滚动过程当中会改变 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 轴坐标或者高度就会 一不当心顺手 学习了滚动到页面各处。

一块儿成长

在困惑的城市里总少不了并肩同行的 伙伴 让咱们一块儿成长。

  • 若是您想让更多人看到文章能够点个 点赞
  • 若是您想激励小二能够到 Github 给个 小星星
  • 若是您想与小二更多交流添加微信 m353839115

微信公众号

本文原稿来自 PushMeTop

相关文章
相关标签/搜索