Xar*_*rus 188 javascript cross-browser back single-page-application
你如何明确地检测用户是否按下了浏览器中的后退按钮?
如何使用#URL
系统在单页Web应用程序中强制使用页内后退按钮?
为什么地球上没有浏览器按钮触发他们自己的事件!?
Xar*_*rus 158
(注意:根据Sharky的反馈,我已经包含了检测退格的代码)
所以,我经常在SO上看到这些问题,并且最近遇到了自己控制后退按钮功能的问题.在为我的应用程序(带有散列导航的单页)搜索最佳解决方案几天后,我想出了一个简单的,跨浏览器,无库的系统来检测后退按钮.
大多数人建议使用:
window.onhashchange = function() {
//blah blah blah
}
Run Code Online (Sandbox Code Playgroud)
但是,当用户使用更改位置哈希的页内元素时,也会调用此函数.当您的用户点击并且页面向后或向前移动时,这不是最好的用户体验.
为了给你一个我的系统的概述,当我的用户在界面中移动时,我正在填充一个带有先前哈希的数组.它看起来像这样:
function updateHistory(curr) {
window.location.lasthash.push(window.location.hash);
window.location.hash = curr;
}
Run Code Online (Sandbox Code Playgroud)
挺直的.我这样做是为了确保跨浏览器支持,以及对旧版浏览器的支持.只需将新哈希传递给函数,它就会为您存储它,然后更改哈希值(然后将其放入浏览器的历史记录中).
我还利用页内返回按钮,使用lasthash
数组在页面之间移动用户.它看起来像这样:
function goBack() {
window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
//blah blah blah
window.location.lasthash.pop();
}
Run Code Online (Sandbox Code Playgroud)
所以这会将用户移回到最后一个哈希,并从数组中删除最后一个哈希(我现在没有前进按钮).
所以.如何检测用户是否使用了我的页内返回按钮或浏览器按钮?
起初我看了window.onbeforeunload
,但无济于事 - 只有在用户要更改页面时才会调用.在使用哈希导航的单页面应用程序中不会发生这种情况.
因此,经过一些挖掘,我看到了尝试设置标志变量的建议.在我的情况下,这个问题是我会尝试设置它,但由于一切都是异步的,因此并不总是及时设置散列更改中的if语句..onMouseDown
并不总是在点击中调用,并将其添加到onclick将不会足够快地触发它.
这是当我开始研究document
和之间的区别时window
.我的最终解决方案是使用标志设置document.onmouseover
,并使用禁用它document.onmouseleave
.
当用户的鼠标位于文档区域内时(读取:呈现的页面,但不包括浏览器框架),我的布尔值设置为true
.只要鼠标离开文档区域,布尔值就会翻转到false
.
这样,我可以window.onhashchange
改为:
window.onhashchange = function() {
if (window.innerDocClick) {
window.innerDocClick = false;
} else {
if (window.location.hash != '#undefined') {
goBack();
} else {
history.pushState("", document.title, window.location.pathname);
location.reload();
}
}
}
Run Code Online (Sandbox Code Playgroud)
你会注意到支票#undefined
.这是因为如果我的数组中没有可用的历史记录,则返回undefined
.我用它来询问用户是否想要使用window.onbeforeunload
事件离开.
因此,简而言之,对于那些不一定使用页内后退按钮或数组来存储历史记录的人:
document.onmouseover = function() {
//User's mouse is inside the page.
window.innerDocClick = true;
}
document.onmouseleave = function() {
//User's mouse has left the page.
window.innerDocClick = false;
}
window.onhashchange = function() {
if (window.innerDocClick) {
//Your own in-page mechanism triggered the hash change
} else {
//Browser back button was clicked
}
}
Run Code Online (Sandbox Code Playgroud)
你有它.一种简单的,由三部分组成的方法来检测后退按钮的使用与页面内元素相关的哈希导航.
编辑:
为了确保用户不使用退格键来触发后退事件,您还可以包含以下内容(感谢@thetoolman 对此问题):
$(function(){
/*
* this swallows backspace keys on any non-input element.
* stops backspace -> back
*/
var rx = /INPUT|SELECT|TEXTAREA/i;
$(document).bind("keydown keypress", function(e){
if( e.which == 8 ){ // 8 == backspace
if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
e.preventDefault();
}
}
});
});
Run Code Online (Sandbox Code Playgroud)
ken*_*orb 67
您可以尝试popstate
事件处理程序,例如:
window.addEventListener('popstate', function(event) {
// The popstate event is fired each time when the current history entry changes.
var r = confirm("You pressed a Back button! Are you sure?!");
if (r == true) {
// Call Back button programmatically as per user confirmation.
history.back();
// Uncomment below line to redirect to the previous page instead.
// window.location = document.referrer // Note: IE11 is not supporting this.
} else {
// Stay on the current page.
history.pushState(null, null, window.location.pathname);
}
history.pushState(null, null, window.location.pathname);
}, false);
Run Code Online (Sandbox Code Playgroud)
注意:为获得最佳结果,您应仅在要实现逻辑的特定页面上加载此代码,以避免任何其他意外问题.
每当当前历史记录条目更改(用户导航到新状态)时,就会触发popstate事件.当用户点击浏览器的后退/前进按钮或发生时history.back()
,history.forward()
,history.go()
方法编程调用.
该event.state
事件的是财产等于历史状态对象.
对于jQuery语法,将其包装起来(在文档准备好后添加偶数监听器):
(function($) {
// Above code here.
})(jQuery);
Run Code Online (Sandbox Code Playgroud)
另请参阅单页面应用程序和HTML5 pushState页面上的示例:
<script>
// jQuery
$(window).on('popstate', function (e) {
var state = e.originalEvent.state;
if (state !== null) {
//load content with ajax
}
});
// Vanilla javascript
window.addEventListener('popstate', function (e) {
var state = e.state;
if (state !== null) {
//load content with ajax
}
});
</script>
Run Code Online (Sandbox Code Playgroud)
这应该兼容Chrome 5 +,Firefox 4 +,IE 10 +,Safari 6 +,Opera 11.5+等.
esc*_*nxr 19
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
alert('hello world');
}
Run Code Online (Sandbox Code Playgroud)
这是唯一对我有用的解决方案(它不是单页网站)。它适用于 Chrome、Firefox 和 Safari。
lla*_*alu 16
正确答案已经存在以回答问题。我想提及新的 JavaScript API PerformanceNavigationTiming,它正在取代已弃用的performance.navigation。
如果用户使用后退或前进按钮登陆您的页面,以下代码将登录控制台“back_forward”。在您的项目中使用它之前,请查看兼容性表。
var perfEntries = performance.getEntriesByType("navigation");
for (var i = 0; i < perfEntries.length; i++) {
console.log(perfEntries[i].type);
}
Run Code Online (Sandbox Code Playgroud)
小智 15
我一直在努力解决这个问题很长一段时间,并采取了上面的一些解决方案来实现它.然而,我偶然发现了一个观察结果,它似乎适用于Chrome,Firefox和Safari浏览器+ Android和iPhone
在页面加载:
window.history.pushState({page: 1}, "", "");
window.onpopstate = function(event) {
// "event" object seems to contain value only when the back button is clicked
// and if the pop state event fires due to clicks on a button
// or a link it comes up as "undefined"
if(event){
// Code to handle back button or prevent from navigation
}
else{
// Continue user action through link or button
}
}
Run Code Online (Sandbox Code Playgroud)
如果这有帮助,请告诉我.如果遗漏了什么,我将很乐意理解.
WP *_*unk 15
我的变体:
const isVisitedViaBackButton = performance && performance.getEntriesByType( 'navigation' ).map( nav => nav.type ).includes( 'back_forward' )
Run Code Online (Sandbox Code Playgroud)
Has*_*hah 12
在javascript中,导航类型2
表示浏览器的后退或前进按钮被点击,浏览器实际上从缓存中获取内容.
if(performance.navigation.type == 2)
{
//Do your code here
}
Run Code Online (Sandbox Code Playgroud)
浏览器:https : //jsfiddle.net/Limitlessisa/axt1Lqoz/
对于移动控制:https : //jsfiddle.net/Limitlessisa/axt1Lqoz/show/
$(document).ready(function() {
$('body').on('click touch', '#share', function(e) {
$('.share').fadeIn();
});
});
// geri butonunu yakalama
window.onhashchange = function(e) {
var oldURL = e.oldURL.split('#')[1];
var newURL = e.newURL.split('#')[1];
if (oldURL == 'share') {
$('.share').fadeOut();
e.preventDefault();
return false;
}
//console.log('old:'+oldURL+' new:'+newURL);
}
Run Code Online (Sandbox Code Playgroud)
.share{position:fixed; display:none; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.8); color:white; padding:20px;
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<title>Back Button Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body style="text-align:center; padding:0;">
<a href="#share" id="share">Share</a>
<div class="share" style="">
<h1>Test Page</h1>
<p> Back button press please for control.</p>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
小智 6
看到这个:
history.pushState(null, null, location.href);
window.onpopstate = function () {
history.go(1);
};
Run Code Online (Sandbox Code Playgroud)
它工作正常......
这肯定会起作用(用于检测后退按钮的单击)
$(window).on('popstate', function(event) {
alert("pop");
});
Run Code Online (Sandbox Code Playgroud)
我能够使用该线程和其他线程中的一些答案来使其在 IE 和 Chrome/Edge 中工作。对我来说,history.pushState在 IE11 中不受支持。
if (history.pushState) {
//Chrome and modern browsers
history.pushState(null, document.title, location.href);
window.addEventListener('popstate', function (event) {
history.pushState(null, document.title, location.href);
});
}
else {
//IE
history.forward();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
422661 次 |
最近记录: |