最近在做微信浏览器网页项目的开发,就是在在微信浏览器中运行网页项目,遇到了各种问题,其中最常见的就是微信浏览器后退时的页面刷新问题。
遇到的问题:
从列表页浏览了10几页数据后,进入其中一个产品的详情页,然后再返回列表页时,页面会强制刷新,之前加载的数据全没了,又要从第一页开始。
经过我在各种手机上的测试之后,发现安卓和ios手机对于页面的刷新机制不一样。
安卓手机:
从列表页进入详情页,再后退回列表页时,页面会强制刷新,也就是说之前异步加载和数据和页面的操作全部没有了。
苹果手机:
从列表页进入详情页,再后退回列表页时,页不会刷新。
解决方案:
原理:利用浏览器的缓存机制
1.页面第一次加载时,判断缓存中是否有数据,如果有,载入缓存中的数据替换页面中的dom节点,并删除缓存中的数据
2.如果缓存中没有数据,执行原本的业务逻辑
3.进入详情页之前,将页面需要缓存的数据保存进缓存中(主要缓存的是dom节点和页面位置)
缓存可以选择cookie,sessionstorage,localstorag,这三者的区别我就不多赘述了,可以自行查询。我选择的是sessionstorage作为缓存使用,以下是demo案例:
列表页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>列表页</title>
<style>
.category_container {
border-bottom: solid 1px red;
}
.category_container div{
display: flex;
justify-content: space-between;
align-items: center;
}
.data-container {
width: 100%;
margin-top: 20px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.data-container .data-item {
width: 45%;
height: auto;
}
.data-img {
width: 100%;
height: 121px;
}
.data-img img{
width: 100%;
height: 121px;
}
.data-desc {
display: flex;
flex-direction: column;
align-items: center;
}
.more {
text-align: center;
}
</style>
</head>
<body>
<div>
<!--产品分类-->
<div class="category_container">
<div>
<span onclick="clickCategory(this)">分类1</span>
<span onclick="clickCategory(this)">分类2</span>
<span onclick="clickCategory(this)">分类3</span>
<span onclick="clickCategory(this)">分类4</span>
<span onclick="clickCategory(this)">分类5</span>
<span onclick="clickCategory(this)">分类6</span>
</div>
</div>
<!--数据列表-->
<div class="data-container">
<div class="data-item" onclick="goDetail()">
<div class="data-img">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578564807152&di=acc376c3356219a18c2d4bfe600b90ed&imgtype=0&src=http%3A%2F%2Fimage.it168.com%2Fn%2F640x480%2F8%2F8343%2F8343572.jpg" alt="">
</div>
<div class="data-desc">
<span>名称:苹果手机</span>
<span>价格:2000元</span>
</div>
</div>
</div>
<div class="more" onclick="createData()">
加载更多
</div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
$(function () {
//初始化页面
init();
})
//初始化页面,从sessionStorage中取出数据
function init(){
let category = sessionStorage.getItem('category');
let scroll = sessionStorage.getItem('scroll');
let data = sessionStorage.getItem('data');
//恢复页面数据
if(null != data && ''!=data){
$('.data-container').html(data); //恢复产品数据
$('.category_container').html(category); //恢复分类数据
$(window).scrollTop(scroll); //恢复页面位置
}else{
//如果sessionStorage数据为空,则用户为第一次进入该页面或者刷新页面
//此时调用原本的业务逻辑
createData();
}
//清空sessionStorage中的数据
sessionStorage.removeItem('scroll');
sessionStorage.removeItem('category');
sessionStorage.removeItem('data');
}
//添加数据
function createData(){
for(let i=0;i<5;i++){
let html = $(".data-item").prop("outerHTML");
$('.data-container').append(html);
}
}
//跳转到详情页面
function goDetail(){
//保存当前页面的位置
sessionStorage.setItem('scroll',$(window).scrollTop());
//保存当前页面已经加载过的分类dom
sessionStorage.setItem('category',$('.category_container').html());
//保存当前页面的数据dom
sessionStorage.setItem('data',$('.data-container').html());
//保存当前加载的页数以及是否有下一页等数据,可根据业务逻辑自行保存数据
//跳转到详情页
location.href = 'detail.html';
}
function clickCategory(item){
$(item).css('color','red').siblings().css('color','black');
}
</script>
</body>
</html>
详情页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>详情页</title>
<style>
</style>
</head>
<body>
<div>
<h1>这是详情页</h1>
</div>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
</script>
</body>
</html>
注意要点:
1.如果页面数据的元素高度是自动而不是固定的话,可能会造成从缓存中恢复页面位置不正确的问题,比如设置图片的高度为auto,这是由于返回页面时,数据和位置恢复了,但此时图片还没有加载出来,页面的整体高度还没有被撑开,而$(window).scrollTop(scroll) 这段恢复页面位置的代码已经执行了,所以位置不正确。