让普通网站页面跳转时显示加载进度条 - 一种实现思路

查看 39|回复 0
作者:lete   

为了方便大家使用,我已经将代码开源,如果觉得不错的话点个 ✨star✨ 支持一下下
欢迎大佬们一起参与维护😁👍
开源仓库: https://github.com/Lete114/page-load-progress
体验 Demo: https://lete114.github.io/page-load-progress/test/index.html

有没有人注意到 GitHub 和 YouTube 这些网站在页面跳转时,网页顶部总是会显示一个加载进度条?
比如:
  • GitHub: 点击进入某个仓库,或者进入某个项目的文件夹时屏幕顶部总是会显示一个加载进度条,并且页面不会刷新
  • YouTube: 点击观看某个视频时,屏幕顶部总是会显示一个加载进度条,并且页面不会刷新

    这个效果是怎么实现的呢?其实我也不知道,也并没有特意去查看或逆向过它们 Web 端的 js 代码,我能想到的办法就只有使用 pjax 或者 turbo、turbolinks。但它们也有一些弊端,需要网站管理员去维护,甚至重新编码调整
    如果页面需要交互或者需要 js 操作 dom 的,如获取页面上的所有外链 a 标签,给 a 标签的 href 属性值开头添加跳转拦截 https://link.example.com/?target=,js 不会再次重载,因为页面跳转是不刷新网页的(它只负责替换网页中变化的结构),得手动重载 js ,以上提到的库它们都有提供重载 js 的解决方案,需要你对网站进行一些调整或代码调整
    正文
    那么如果不使用这些库如何让传统的普通网站(指点击链接后页面跳转会刷新页面)实现这一功能呢?
    prefetch
    关于 prefetch 的作用自己看 MDN prefetch

    prefetch 兼容性表格 (Safari 全版本不支持 prefetch)
    自从 IE 浏览器下岗后,Safari 浏览器就变成了新一代 IE 浏览器

    使用 link 标签 rel 属性的 prefetch 值,然后通过监听 link 标签的 onload 事件即可知道,页面已经加载完成
    function prefetch(url){
        var link = document.createElement('link')
        link.rel = 'prefetch'
        link.href = url
        link.onload = function(){
          window.open(url)
        }
        document.head.appendChild(link)
    }
    阻止 a 标签默认事件
    prefetch 只对当前标签页且同源的 HTML 管用,如果是其它资源如 js 、css 、font 、img 等可以不是同源,但必须在同一个标签页内才管用,否则就会失效 (我说的也不一定对,MDN 也没有这方面的详细说明。以上只是我在实际测试中得到的结论,如有问题欢迎各位大佬在评论区补充,感谢)
    获取页面上的所有 a 标签(内链)
    const aTags = document.querySelector('a[href]:not([target^=_]):not([download])')
    aTags.forEach((el)=>{
      window.addEventListener('click', function (event) {
        const target = event.target
        const href = target.href
        if(href && location.origin === new URL(href).origin){
          event.preventDefault()
          // 写进度条的逻辑
          prefetch(href)
          // 或者改造 prefetch 函数将 onload 最为回调函数传入
          // prefetch(href,()=> {
          //   // 触发 onload 后让进度条加载到 100% 然后就调用 window.open(href) 完美实现
          //   window.open(href)
          // })
        }
      })
    })
    总结
    以上便是页面跳转加载进度条的实现思路,以及核心代码逻辑,如有问题欢迎各位大佬指出,也欢迎各位大佬 PR 为开源项目做贡献
  • 您需要登录后才可以回帖 登录 | 立即注册

    返回顶部