如何确定用户是否在浏览器中按下了返回按钮?
如何使用#URL
系统在单页面Web应用程序中强制使用内部返回按钮?
为什么浏览器的后退按钮不会触发它们自己的事件!?
如何确定用户是否在浏览器中按下了返回按钮?
如何使用#URL
系统在单页面Web应用程序中强制使用内部返回按钮?
为什么浏览器的后退按钮不会触发它们自己的事件!?
window.onhashchange = function() {
//blah blah blah
}
然而,当用户使用内部元素更改位置哈希时,该函数也将被调用。当用户单击并且页面向后或向前转换时,这并不是最好的用户体验。
为了给您一个我系统的概要,我正在填充一个数组,其中包含用户在界面上移动时先前的哈希值。它看起来像这样:
function updateHistory(curr) {
window.location.lasthash.push(window.location.hash);
window.location.hash = curr;
}
非常简单。我这样做是为了确保跨浏览器的支持,以及对旧版浏览器的支持。只需将新哈希传递给函数,它就会为您存储它,然后更改哈希(然后将其放入浏览器的历史记录中)。
我还利用一个在页面内部的后退按钮,使用lasthash
数组将用户从一个页面移动到另一个页面。它看起来像这样:
function goBack() {
window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
//blah blah blah
window.location.lasthash.pop();
}
因此,这将把用户带回到最后一个哈希,并从数组中删除该哈希(我现在没有前进按钮)。
那么,如何检测用户是使用我的内部页面返回按钮还是浏览器按钮?
起初,我看了一下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();
}
}
}
请注意对于#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
}
}
就是这样。一种简单的、三部分的方法,用于检测后退按钮的使用与页面内元素相比,以实现哈希导航。
编辑:
为了确保用户不使用退格键触发返回事件,您还可以包括以下内容(感谢@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();
}
}
});
});
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);
注意:为了获得最佳效果,您应该仅在需要实现逻辑的特定页面上加载此代码,以避免任何其他意外问题。
每当当前历史记录项更改(用户导航到新状态)时,都会触发popstate事件。当用户单击浏览器的后退/前进按钮或以编程方式调用history.back()
、history.forward()
、history.go()
方法时发生这种情况。
event.state
是事件的属性,等于历史状态对象。
对于jQuery语法,请将其包装在中(以在文档就绪后添加事件监听器):
(function($) {
// Above code here.
})(jQuery);
另请参见:window.onpopstate on page load
此外,Single-Page Apps and 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>
这应该与Chrome 5+,Firefox 4+,IE 10+,Safari 6+,Opera 11.5+及类似版本兼容。
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
alert('hello world');
}
这是唯一一个对我有效的解决方案(它不是单页网站)。 它在 Chrome、Firefox 和 Safari 中都可以正常工作。
popstate
事件(之前的解决方案)无法在按下“返回”按钮时触发。 - Hermann Schwarz我曾经为这个要求苦苦挣扎了很长时间,尝试了一些上面提到的解决方案来实现它。然而,我偶然发现了一个观察结果,并且它似乎适用于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
}
}
如果这有帮助,请告诉我。如果我漏掉了什么,我很乐意了解。
正确答案已经存在以回答这个问题。我想提及一个新的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);
}
在JavaScript中,导航类型2
表示浏览器的后退或前进按钮被点击,并且浏览器实际上是从缓存中获取内容。
if(performance.navigation.type == 2)
{
//Do your code here
}
我的变量:
const isVisitedViaBackButton = performance && performance.getEntriesByType( 'navigation' ).map( nav => nav.type ).includes( 'back_forward' )
这肯定有效(用于检测后退按钮点击)
$(window).on('popstate', function(event) {
alert("pop");
});
请看这个:
history.pushState(null, null, location.href);
window.onpopstate = function () {
history.go(1);
};
它正常工作...
浏览器: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);
}
.share{position:fixed; display:none; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.8); color:white; padding:20px;
<!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>
ongoback
事件的提案:https://discourse.wicg.io/t/set-back-button-url-in-pwas/4112 - collimarco还没有答案
(九年后的hh)。 - undefined