标题显而易见,要说两种情况:重新打开页面或者返回某个页面时滚动到上次离开时的位置,以及不滚动保持在顶部。
滚动
这也有两种情况:页面重新打开,与返回某个页面。 如果是前者,必定用cookie 或者localStorage 。或者麻烦一点的、在webview中用其他手段。总之这个必须有存储。
然后在组件的activited 或是window.onload 时取出存储内容改变scrollTop 。非常牛逼。
对于原生页面,如果在关键位置没有图片和表格,可以尝试在onreadystatechange 中完成,不必等到onload 。 关于这点,背景和降级处理等具体可以参考笔者的这篇文章:点击跳转
若是第二种情况,则只需要临时缓存即可,这里拿vue演示一下: 有两个方案。其一,利用路由中的meta ,在离开页面时缓存 top 信息
{
path: "/user",
name: "user",
component: () => import("../views/user.vue"),
meta: { scrollTop: 0, keepScroll: true }
},
router.beforeEach((to, from, next) => {
if (from.meta.keepScroll) {
const $content = document.querySelector("#app");
const scrollTop = $content ? $content.scrollTop : 0;
from.meta.scrollTop = scrollTop;
}
next();
});
然后在回到当前页面时拿到临时缓存,并赋值
export const getScroll = vm => {
const scrollTop = vm.$route.meta.scrollTop;
const $content = document.querySelector('#app');
if (scrollTop && $content) {
$content.scrollTop = scrollTop;
}
};
组件内
import * as util from '@/utils/';
activeted() {
util.getScroll(this);
}
其二,利用keep-alive 缓存整个页面。但是仅限于没有实时数据变动的页面
<template>
<div id="app">
<keep-alive >
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
路由配置里 在需要被缓存的页面meta里配置keepAlive属性
{
path: '/index',
name: 'index',
meta: {
title: ' ',
keepAlive: true,
},
component: () => import('@/components/index'),
},
组件内在beforeRouteLeave 钩子函数中,将该页面的 keepAlive 属性设为false
beforeRouteLeave (to, from, next) {
from.meta.keepAlive = false;
next();
},
然后需要在下一个页面进行配置,页面返回时设置上一个页面的 keepAlive 为true
beforeRouteLeave (to, from, next) {
if (to.path == "/index") {
to.meta.keepAlive = true;
} else {
to.meta.keepAlive = false;
}
next();
},
不滚动
其实有的页面我们会发现,体验下来觉得并不想让重新进入时回到上一次浏览的地方。 理论上说这里不加上面提到的各种方法不就行了?其实不然。 「重新进入」也分两种情况:重新打开这个页面,和刷新页面。 前者大可不必关心。对于后者,在比如QQ内置浏览器中,短时间内重新打开相同页面的逻辑和普通刷新是一样的。
在浏览器中,普通刷新会“记住”用户上次的位置似乎是个惯例了。如何在页面刷新时保持在顶部呢? 浏览器提供了history API实现。其兼容性还算不错,除了IE外基本目前使用的浏览器都可以使用了。
if (history.scrollRestoration) {
history.scrollRestoration = 'manual';
}
强制刷新(CTRL + F5)不会“记住”用户位置
|