这个问题类似于this one,但我想知道是否有可能在不依赖PhoneGap / Ionic或Cordova的情况下实现这种行为.
解决方法
首先,当用户所在的页面没有浏览器历史记录时,按后退按钮会立即关闭该应用程序.
我们可以通过在首次打开应用时添加以前的历史记录状态来阻止这种情况:
window.addEventListener('load',function() { window.history.pushState({},'') })
pushState() takes three parameters: a state object,a title (which is currently ignored),and (optionally) a URL[…] if it isn’t specified,it’s set to the document’s current URL.
所以现在用户必须按两次后退按钮.一个印刷机将我们带回原始历史状态,下一个印刷机关闭应用程序.
第二部分是我们挂钩窗口的popstate事件,只要浏览器通过用户操作在历史记录中向后或向前导航(当我们调用history.pushState时就不会这样).
A popstate event is dispatched to the window each time the active history entry changes between two history entries for the same document.
所以现在我们有:
window.addEventListener('load','') }) window.addEventListener('popstate','') })
加载页面后,我们立即创建一个新的历史记录条目,每次用户按“返回”转到第一个条目时,我们再次添加新条目!
当然,这种解决方案对于没有路由的单页应用程序来说非常简单.它必须适用于已使用历史记录API的应用程序,以使当前网址与用户导航的位置保持同步.
为此,我们将为历史记录的状态对象添加一个标识符.这将允许我们利用popstate事件的以下方面:
If the activated history entry was created by a call to history.pushState(),[…] the popstate event’s state property contains a copy of the history entry’s state object.
所以现在在我们的popstate处理程序中,我们可以区分我们用来阻止后退按钮关闭应用程序行为的历史记录条目与用于在应用程序内进行路由的历史记录条目,并且只有当它特别具有时才重新推送我们的预防性历史记录条目弹出:
window.addEventListener('load',function() { window.history.pushState({ noBackExitsApp: true },function(event) { if (event.state && event.state.noBackExitsApp) { window.history.pushState({ noBackExitsApp: true },'') } })
最后观察到的行为是,当按下后退按钮时,我们要么返回我们的渐进式网络应用程序路由器的历史记录,要么我们保持在应用程序打开时看到的第一页上.