最近做项目遇到一个问题,就是Vue滚动不固定,网上找了一些资料,说下 vue 固定滚动位置的处理办法.

问题描述:
通常见于 列表页List -> 详情页Detail 的情况, 从列表的某一项x 进入到详情页, 再返回的时候, 希望列表的位置固定在x, 而不是回到顶部了.
vue-router 里面是有一个 scrollBehavior 的, 但是这个玩意只能在 history 模式下面使用, 而我用的 hash 模式.
所以我们要自己实现嘛, 思路简单:List 里面监听滚动, 记录滚动位置 pos, 从 Detail 返回到 List 里面的时候, 读取 pos.
mounted () {
// 读
setTimeut(function(){
document.body.scrollTop = parseInt(sessionStorage.getItem('pos'));
}, 1000);
// 存
window.onscroll = function () {
sessionStorage.setItem('pos', document.body.scrollTop);
}
}
遇见了一个问题:
每次返回 List, 都是直接滚动到顶部, 每次都是, 每次都是! 把 pos 打印出来, 发现是 0, 而不是我们所存的值. 日了, 明明切换之前还是的, 回来就不是了.
然后发现了路由每次切换都会触发 onscroll 事件, 日了狗, 为毛.我都没有滚动页面, 为什么会触发 onscroll 事件。
刚开始怀疑 hash 变化会导致 onscroll 事件的触发, 所以我就在浏览器里面手动输入了几个不存在的路由:
/foo /bar
没有发现 scroll 被触发, 所以这个嫌疑排出.
然后怀疑 vue-router 里面是不是绑定了 scroll 事件, 没发现然后又想, 没绑定 scroll 事件, 那么修改 scrollTop 值会不会也触发 scroll 事件.
好吧还发现新知识点了:
scrollTop 值的改变, 的确会触发 scroll 事件.
那么我就想, 是不是 vue-router 里面存在修改 scrollTop 值的行为, 也没有发现.
然后我又想, 数据是动态渲染的, 所以是不是和元素的增删改查相关。
元素增加-> 页面高度变了 -> 页面高度变化, 也触发 scroll 事件?
所以我用 vue-cli 新建了项目, 放了两个没有增删改查的路由
然后日了狗的, 我看见从 foo -> bar -> foo, 的时候, foo的滚动条位置还在之前我滚动到的地方.
突然想起来浏览器是可以自己记录滚动条位置的.
是不是浏览器干的?
从详情页返回到列表页面, 列表会重新渲染, 时序大概是这样:
返回列表页 1
渲染页面 2
而浏览器恢复滚动条的位置的操作, 是在 1 和 2 之间, 这个时候就出问题了:如果你页面上面的数据都是渲染出来的, 浏览器就会发现:
页面的高度<=屏幕的高度, 不存在滚动条, 此时 document.body.scrollTop = 0;
所以会设置 document.body.scrollTop = 0
修改了 document.body.scrollTop 触发了 scroll 事件, scroll 里面又重写了 pos
等你数据渲染结束之后, 读到的就是 0了.
如果发现你页面高度大于屏幕高度, 但是页面高度是 n, 而 pos 的值是: n + x, 比当前页面的最大的 scrollTop 值还大, 这个时候, document.body.scrollTop 的值就会等于 n.
当你的数据渲染结束, 开始定位, 日了, 没定准.
所以我们要解决这个问题.
当然是想到了 keep-alive, 刚启用的时候, 发现的确不错. 但是同时也发现:
列表项目靠前的, 往返操作的定位都很准, 越往后越不行, 直接拉到底, 再返回发现定位到的一般都是第二个第三个列表项目.
所以这个就很有意思了, 我大概猜测了一下浏览器的滚动位置恢复行为:
当 hashchange 的时候。拿到当前页面的 document.body.scrollTop 值, 和自己存储的滚动条位置。二者取最小的值, 设置成当前的 document.body.scrollTop 的值, 当使用 keep-alive 的时候, 因为 hashchange 事件处理和页面渲染是并行的, 所以有时hashchange 拿到的 document 的高度是已经渲染过几个元素的高度, 这个就是为什么定不准的原因.
好吧, 现在的情况是:
keep-alive 定不准, 不可靠, 所以需要我们自己来重新定位.
ok, 1 先绑定 scroll 事件:
var map = {};
window.onscroll = function() {
map[location.hash] = document.body.scrollTop;
}
2 再屏蔽掉浏览器自动恢复滚动位置行为带来的影响
a 在 hashchange 时强制 document.body.scrollTop = 0
b 在 scroll 事件里面, 当 document.body.scrollTop = 0 的时候不做 存操作.
var map = {};
window.onhashchange = function() {
document.body.scrollTop = 0;
}
window.onscroll = function() {
if (document.body.scrollTop) {
// 存
map[location.hash] = document.body.scrollTop;
} else {
// 读
}
}
3 在读操作里面, 设置一个定时任务, 去判断 document.body.scrollTop 的值和你保存的位置是不是相同的
var map = {};
window.onhashchange = function() {
document.body.scrollTop = 0;
}
window.onscroll = function() {
if (document.body.scrollTop) {
// 存
map[location.hash] = document.body.scrollTop;
} else {
var timer = null;
timer = setInterval(function(){
if (document.body.scrollTop == map[location.hash]) {
clearInterval(timer);
} else {
document.body.scrollTop = map[location.hash];
}
}, 20);
}
}
到这里实际上已经大体实现了, 返回恢复滚动条位置的功能, 而上面的代码需要更多的优化,
具体代码见:项目地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Vue固定滚动位置
# Vue页面滚动固定位置
# Vue实现渲染数据后控制滚动条位置(推荐)
# vue实现滚动条到顶部或者到指定位置
# vue中实现点击按钮滚动到页面对应位置的方法(使用c3平滑属性实现)
# vue监听页面中的某个div的滚动事件并判断滚动的位置
# Vue滚动到指定位置的多种方式示例详解
# Vue滚动页面到指定位置的实现及避坑
# Vue列表如何实现滚动到指定位置样式改变效果
# 解决vue无法设置滚动位置的问题
# vue通过滚动行为实现从列表到详情
# 返回列表原位置的方法
# vue-scroller记录滚动位置的示例代码
# Vue页面返回滚动位置恢复(keep-alive滚动记忆)
# 都是
# 滚动条
# 几个
# 就会
# 我用
# 不存在
# 好吧
# 这个时候
# 详情页
# 一个问题
# 绑定
# 而不是
# 如果你
# 是在
# 就在
# 还在
# 是有
# 是这样
# 我都
# 就不
相关文章:
网站制作新手教程,新手建设一个网站需要注意些什么?
青浦网站制作公司有哪些,苹果官网发货地是哪里?
专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?
建站之星导航菜单设置与功能模块配置全攻略
网站设计制作企业有哪些,抖音官网主页怎么设置?
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
h5在线制作网站电脑版下载,h5网页制作软件?
免费制作小说封面的网站有哪些,怎么接网站批量的封面单?
PHP正则匹配日期和时间(时间戳转换)的实例代码
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
如何在宝塔面板创建新站点?
高端建站如何打造兼具美学与转化的品牌官网?
如何在VPS电脑上快速搭建网站?
零服务器AI建站解决方案:快速部署与云端平台低成本实践
如何在Windows环境下新建FTP站点并设置权限?
建站之星×万网:智能建站系统+自助建站平台一键生成
网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?
建站之星如何实现网站加密操作?
建站主机SSH密钥生成步骤及常见问题解答?
建站OpenVZ教程与优化策略:配置指南与性能提升
网站制作公司,橙子建站是合法的吗?
盘锦网站制作公司,盘锦大洼有多少5G网站?
如何用IIS7快速搭建并优化网站站点?
如何零基础开发自助建站系统?完整教程解析
定制建站哪家更专业可靠?推荐榜单揭晓
济南网站制作的价格,历城一职专官方网站?
如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?
如何做网站制作流程,*游戏网站怎么搭建?
如何彻底删除建站之星生成的Banner?
5种Android数据存储方式汇总
无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?
如何通过西部数码建站助手快速创建专业网站?
如何通过商城免费建站系统源码自定义网站主题?
建站主机选哪种环境更利于SEO优化?
如何通过WDCP绑定主域名及创建子域名站点?
如何获取开源自助建站系统免费下载链接?
如何配置IIS站点权限与局域网访问?
广德云建站网站建设方案与建站流程优化指南
如何在阿里云ECS服务器部署织梦CMS网站?
淘宝制作网站有哪些,淘宝网官网主页?
C++中引用和指针有什么区别?(代码说明)
非常酷的网站设计制作软件,酷培ai教育官方网站?
如何在阿里云通过域名搭建网站?
实现虚拟支付需哪些建站技术支撑?
宁波自助建站系统如何快速打造专业企业网站?
nginx修改上传文件大小限制的方法
如何用免费手机建站系统零基础打造专业网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。