实验:揣测浏览器history下的滚动条处理

165 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

背景

事情是这样的,某一天我屁颠屁颠的fish时,张三突然交代我一个任务,就是给现有的系统加上一个页面缓存,实现前进后退时能够保存历史行为,包括滚动位置等。

看着SPA下的react-router,此时我打开package.json,发现这是v5下的路由,然而事情并不是这么简单,当我点击在当前页新开一个页面时(就是在当前地址栏push了一个新地址),有的页面居然置顶了,有的页面会滚动到某个位置。

于是我通过百度路由缓存方案,找到了一个叫做react-router-cache-route的第三方库,该库实现了节点的复用,一些情况下保证了前进后退滚动条位置状态的记录,当push新地址时还是有些问题。

后来通过该库在路由下拦截了一层,判断history的push行为给予window.scrollTo(0,0)的处理。

好吧,这些都是后话,今天主要的是探讨浏览器history下的滚动条行为。

实验

下面是test1页面的代码,我们先把这个这个页面下滑到一定位置,然后点击跳转到test2页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            width: 50vh;
            height: 50vh;
        }
        .box1{
            background-color: red;
        }
        .box2{
            background-color: green;
        }
        .box3{
            background-color:aqua;
        }

    </style>
</head>
<body>
    <div class="box1"></div>
    <a href="./test2.html">test2</a>
    <div class="box2"></div>
    <div class="box3"></div>
</body>
</html>


test1.png

上面是test1页面跳转前的截图,当我们点击a标签后,跳转到test2页面,此时新开页面的滚动位置是置顶的。(test2页面和上一个页面是一样,只是更改了div的颜色)

test2.png

此时有的小伙伴可能不这么认为,那我们继续测试跳转,test3页面同之前页面一样的结构,只是每个div高度变成110vh。

test3.png

我们在test3页面下滑一定位置,然后回退两个页面到test1,接着继续前进页面,重复测试,我们发现滚动位置都会被记录,而通过a标签跳转的新页面始终是置顶的。

通过观察网络面板,我们也能发现前进和后退都会请求html页面。

当我们在某个滚动位置调用history这个api,push一个地址时,地址改变了,页面滚动位置并没有发生变化。

test4.png

那我们通过这些现象姑且得出这样的结论:

浏览器history能够记录当时的访问位置,当我们回退或者前进时,都能够滚动到当时的滚动位置。而往地址栈push地址的行为并不会改变当前页面的状态包括滚动位置。

结论

  • 新开页面,滚动条置顶(无论是a标签替换当前窗口还是新建标签复制粘贴地址)
  • 滚动一段距离,打开新页面并替换当前页面,再滑动新页面到一段距离。回退,页面记录滚动条位置,再前进返回新开的页面,滚动距离依旧存在。
  • 通过浏览器history这个接口push地址的行为,滚动条位置不变。