(带效果动图)H5在详细页点返回,返回时列表页停留在原来的位置

通过使用Vue和Vant构建H5页面,作者遇到一个问题:在移动端浏览器(如微信内置浏览器)中,列表页滚动后跳转详情再返回会刷新页面。经研究发现,使用iframe内嵌详情页面,并监听返回键事件,可以解决这一问题。当点击返回时,iframe隐藏,页面状态得以保留。详细实现包括HTML结构、Vue方法及内嵌网页的返回按钮处理。
摘要由CSDN通过智能技术生成

前言

  • 有了vue以后,我H5都是用vue写了,然后使用vant(轻量、可靠的移动端 Vue 组件库)布局,一个网页就特别容易的完成了,然后就是要优化网页。
  • 在工作中,H5主要被用来内嵌进移动端(ios、小程序、安卓),而各大应用中,用的最多的数据结构就是列表。用H5做列表网页,有一个很大的弊端就是:往下滑列表,然后点击跳转到详情网页再返回时,会发现列表页刷新并返回顶部了。
  • 这个弊端和浏览器有关系。(具体原因感兴趣的自查百度)
    • Microsoft Edge浏览器就能返回时列表停留在原来的位置
    • 红米手机上自带的浏览器也能返回时列表停留在原来的位置
    • 谷歌浏览器返回时就会刷新页面滑到顶部
    • ios、安卓的webview返回时就会刷新页面滑到顶部(如微信内部访问网页)

未优化前效果展示

在微信内部浏览器,往下滑列表,然后点击跳转到详情网页再返回时,会发现列表页刷新并返回顶部了,如图所示:

优化后效果展示

还是在微信内部浏览器

实现

思路

  • 既然是因为跳转到新的网页然后返回才会导致这个问题,我就不让跳到新网页,直接在原网页里内嵌。内嵌网页的方式:iframe。
  • 做到内嵌网页后,我们要实现点击安卓手机的返回键能够把这个内嵌网页关掉。应该有很多种方式,我自己做的是:监听返回键事件,然后执行自己的操作。

代码

1、html 代码

说明:

  • 有一个大盒子div,宽度高度与屏幕一样,即全屏(width: 100%; height: 100%;),显示位置置前(position: fixed; z-index: 999;),这两条一定要。
  • 居中 display: flex; justify- content: center;  align-items: center;
  • showPage 来控制内嵌网页的显示与隐藏。
  • iframe 的宽高为父容器的100%,即全屏。src放入子页面的url路径。
<div v-if="showPage == '1' " style="position: fixed; z-index: 999;display: flex; justify-    
    content: center;  align-items: center; background: white; width: 100%; height: 100%;">

    <iframe frameborder=0 width=100% height=100% :src="subPage"></iframe>

</div>

2、javascript vue 代码

说明:按照思路

  • 用变量showPage 来控制内嵌网页的显示与隐藏;
  • pushHistory()放入停留在之前浏览的位置的url,这个一定不要漏,不然返回的时候就直接退出列表页了!
  • 监听返回键:返回上一个网页的事件是无法拦截的,所以我们只能添加停留在之前浏览的位置的url也就是原url+#,然后在返回键事件里把内嵌网页隐藏掉,我们就能成功的使H5返回时不刷新页面,列表保持在原来的位置。
data: {
    showPage: "0", // showPage初始化,0隐藏,1显示
    ......
}

methods: {
    // 使用pushState方法往history里增加url链接:原url加个#,还是原页面并且停留在之前浏览的位置
    pushHistory() {
        var state = {
            title: "title",
            url: "#"
        }
        window.history.pushState(state, "title", "#");
    },

    // 打开内嵌网页
    getScore(name, score) {
        const that = this
        // 内嵌网页的url
        that.subPage = 'score.html?name=' + name +'&score=' + score
        // 内嵌网页显示
        that.showPage = '1'
        // 放入停留在之前浏览的位置的url,这个一定不要漏,不然返回的时候就直接退出列表页了!
        that.pushHistory()
        // 监听返回键
        window.addEventListener("popstate", function(e) {
            // 内嵌网页隐藏
            that.showPage = '0'
        })
    },

    // 打开另一个内嵌网页 
    getRatings(name, date) {
        const that = this
        that.subPage = 'ratings.html?name=' + name + '&date=' + date;
        that.showPage = '1'
        that.pushHistory()
        window.addEventListener("popstate", function(e) {
            that.showPage = '0'
		})
    },
    ......
}

3、内嵌网页,标题栏的返回按钮点击事件(ios不像安卓手机那样屏幕底部有返回键,所以网页顶部要布置一个返回按钮)

onBack() {
    window.history.back(-1);//返回上一层
},

参考资料

JS监听浏览器的返回事件_柏灿的博客-CSDN博客_监听浏览器返回事件

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你可以使用 `keep-alive` 组件来缓存列表,以保持其状态不变。然后使用路由参数来传递当前位置的信息。在跳转到详情,将当前位置信息作为参数传递给详情,以便在返回能够准确地回到原来位置。 以下是示例代码: 列表: ```html <template> <div> <keep-alive> <ul> <li v-for="item in items" :key="item.id"> <router-link :to="{ name: 'detail', params: { id: item.id, position: getPosition() } }">{{ item.title }}</router-link> </li> </ul> </keep-alive> </div> </template> <script> export default { data() { return { items: [...], // 列表数据 scrollTop: 0 // 当前滚动位置 } }, methods: { getPosition() { // 获取当前滚动位置 return this.$refs.list.scrollTop } }, mounted() { // 监听滚动事件,更新滚动位置 this.$refs.list.addEventListener('scroll', () => { this.scrollTop = this.$refs.list.scrollTop }) } } </script> ``` 详情: ```html <template> <div> <h1>{{ item.title }}</h1> <p>{{ item.content }}</p> <button @click="goBack">返回</button> </div> </template> <script> export default { data() { return { item: {}, // 详情数据 position: 0 // 列表滚动位置 } }, methods: { goBack() { // 返回列表,并滚动到原来位置 this.$router.back() setTimeout(() => { this.$refs.list.scrollTop = this.position }, 0) } }, mounted() { // 获取详情数据 const id = this.$route.params.id this.item = this.items.find(item => item.id === id) // 获取列表滚动位置 this.position = this.$route.params.position } } </script> ``` 注意,以上代码仅为示例,具体实现可能需要根据实际情况进行调整。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值