更新:2020年7月28日08:51:11
基础库2.12.0起,可以调用wx.enableAlertBeforeUnload监听原生右上角返回、物理返回以及wx.navigateBack时弹框提示
AIP详情请看:
https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.enableAlertBeforeUnload.html
//========================================
怎么监听小程序的返回键?
应该有很多人想要监听用户的这个动作吧,但是很遗憾,小程序不会给你这个API的,那是不是就没辙了?
幸好我们还可以自定义导航栏,这样一来我们就可以监听用户的这一动作了。
什么?这你已经知道啦?
那好咱们就不说自定义导航栏的返回监听了,说一下物理返回和左滑?右滑?(不管了,反正是滑)返回上一页怎么监听。
监听物理返回
首先说一下这个监听方法的缺点,虽说是监听,但是还是无法真正意义上的监听并拦截来阻止页面跳转,页面还是会返回上一页,而后重新载入刚刚的页面,如果这不是你想要的,那可以不用往下看了
其次说一下用到什么东西: wx.onAppRoute、wx.showModal
最后是一些主要代码:
重写wx.showModal,主要是加个confirmStay参数和使wx.showModal Promise化
const {
showModal
} = wx;
Object.defineProperty(wx, 'showModal', {
configurable: false, // 是否可以配置
enumerable: false, // 是否可迭代
writable: false, // 是否可重写
value(...param) {
return new Promise(function (rs, rj) {
let { success, fail, complete, confirmStay } = param[0]
param[0].success = (res) => {
res.navBack = (res.confirm && !confirmStay) || (res.cancel && confirmStay)
wx.setStorageSync('showBackModal', !res.navBack)
success && success(res)
rs(res)
}
param[0].fail = (res) => {
fail && fail(res)
rj(res)
}
param[0].complete = (res) => {
complete && complete(res)
(res.confirm || res.cancel) ? rs(res) : rj(res)
}
return showModal.apply(this, param); // 原样移交函数参数和this
}.bind(this))
}
});
使用wx.onAppRoute实现返回原来的页面
wx.onAppRoute(function (res) {
var a = getApp(), ps = getCurrentPages(), t = ps[ps.length - 1],
b = a && a.globalData && a.globalData.pageBeforeBacks || {},
c = a && a.globalData && a.globalData.lastPage || {}
if (res.openType == 'navigateBack') {
var showBackModal = wx.getStorageSync('showBackModal')
if (c.route && showBackModal && typeof b[c.route] == 'function') {
wx.navigateTo({
url: '/' + c.route + '?useCache=1',
})
b[c.route]().then(res => {
if (res.navBack){
a.globalData.pageBeforeBacks = {}
wx.navigateBack({ delta: 1 })
}
})
}
} else if (res.openType == 'navigateTo' || res.openType == 'redirectTo') {
if (!a.hasOwnProperty('globalData')) a.globalData = {}
if (!a.globalData.hasOwnProperty('lastPage')) a.globalData.lastPage = {}
if (!a.globalData.hasOwnProperty('pageBeforeBacks')) a.globalData.pageBeforeBacks = {}
if (ps.length >= 2 && t.onBeforeBack && typeof t.onBeforeBack == 'function') {
let { onUnload } = t
wx.setStorageSync('showBackModal', !0)
t.onUnload = function () {
a.globalData.lastPage = {
route: t.route,
data: t.data
}
onUnload()
}
}
t.onBeforeBack && typeof t.onBeforeBack == 'function' && (a.globalData.pageBeforeBacks[t.route] = t.onBeforeBack)
}
})
改造Page
const myPage = Page
Page = function(e){
let { onLoad, onShow, onUnload } = e
e.onLoad = (() => {
return function (res) {
this.app = getApp()
this.app.globalData = this.app.globalData || {}
let reinit = () => {
if (this.app.globalData.lastPage && this.app.globalData.lastPage.route == this.route) {
this.app.globalData.lastPage.data && this.setData(this.app.globalData.lastPage.data)
Object.assign(this, this.app.globalData.lastPage.syncProps || {})
}
}
this.useCache = res.useCache
res.useCache ? reinit() : (onLoad && onLoad.call(this, res))
}
})()
e.onShow = (() => {
return function (res) {
!this.useCache && onShow && onShow.call(this, res)
}
})()
e.onUnload = (() => {
return function (res) {
this.app.globalData = Object.assign(this.app.globalData || {}, {
lastPage: this
})
onUnload && onUnload.call(this, res)
}
})()
return myPage.call(this, e)
}
在需要监听的页面加个onBeforeBack方法,方法返回Promise化的wx.showModal
onBeforeBack: function () {
return wx.showModal({
title: '提示',
content: '信息尚未保存,确定要返回吗?',
confirmStay: !1 //结合content意思,点击确定按钮,是否留在原来页面,confirmStay默认false
})
}
运行测试,Oj8K
是不是很简单,马上去试试水吧,效果图就不放了,静态图也看不出效果,动态图懒得弄,想看效果的自己运行代码片段吧
<p style="animation: weuiLoading 1s ease-in-out infinite;animation-delay:2s;-webkit-animation-delay:2s;background-color: yellow; color: red; padding: 6px 10px;margin-right: 5px;border-radius: 10%;box-shadow: 0px 0px 9px -2px #000;display: inline-block;">是</p> <p style="animation: weuiLoading 1s ease-in-out infinite;animation-delay:2s;-webkit-animation-delay:2s;background-color: yellow; color: orange; padding: 6px 10px;margin-right: 5px;border-radius: 10%;box-shadow: 0px 0px 9px -2px #000;display: inline-block;">这样</p> <p style="animation: weuiLoading 1s ease-in-out infinite;animation-delay:2s;-webkit-animation-delay:2s;background-color: yellow; color: yellow; padding: 6px 10px;margin-right: 5px;border-radius: 10%;box-shadow: 0px 0px 9px -2px #000;display: inline-block;">吗</p>
<p style="animation: weuiLoading 1s ease-in-out infinite;animation-delay:2s;-webkit-animation-delay:2s;background-color: yellow; color: orange; padding: 6px 10px;margin-right: 5px;border-radius: 10%;box-shadow: 0px 0px 9px -2px #000;display: inline-block;">这样</p>
<p style="animation: weuiLoading 1s ease-in-out infinite;animation-delay:2s;-webkit-animation-delay:2s;background-color: yellow; color: yellow; padding: 6px 10px;margin-right: 5px;border-radius: 10%;box-shadow: 0px 0px 9px -2px #000;display: inline-block;">吗</p>
右上角返回?左上角?
监
听
物
理
返
回
很不错
点赞,收藏,评论 三连!
楼主你好,返回监听必须要return 一个弹窗么,可以不弹么,有些业务逻辑不需要再次弹窗确认了
符合不需要弹框的情况时,wx.removeStorageSync('showBackModal') 就行
或者是wx.setStorageSync('showBackModal', false)
要弹框再wx.setStorageSync('showBackModal', true)
单
纯的
试试
若认为该回答有用,给回答者点个[ 赞 ]
onUnload
用这个判断也可以 都是要跳到上个页面 然后判断 再跳回来 onUnload 这个比较简单点
监
听
物
理
返
回
我在uni app 试了试,它好像是先返回上个页面,再重新跳回当前页面
二万人