如何检测浏览器后退button事件 – 跨浏览器

您如何明确检测用户是否按下了浏览器的后退button?

如何使用#URL系统强制在单个页面Web应用程序内使用页面内的后退button?

为什么地球上没有浏览器后退button发射自己的事件!?

(注意:根据Sharky的反馈,我已经包含了检测退格的代码)

所以,我经常看到这些问题,最近碰到了自己控制后退buttonfunction的问题。 在为我的应用程序寻找最佳解决scheme(带有哈希导航的单页)几天后,我想出了一个简单的,跨浏览器的,无库的系统来检测后退button。

大多数人推荐使用:

 window.onhashchange = function() { //blah blah blah } 

但是,当用户使用改变位置散列的页内元素时,也会调用此函数。 当用户点击并且页面向后或向前移动时,不是最好的用户体验。

为了给你一个我的系统的总体概述,当我的用户在界面中移动时,我将填充一个具有前一个哈希值的数组。 它看起来像这样:

 function updateHistory(curr) { window.location.lasthash.push(window.location.hash); window.location.hash = curr; } 

非常直截了当。 我这样做是为了确保跨浏览器的支持,以及对旧浏览器的支持。 只需将新散列传递给该函数,然后将其存储起来,然后更改散列(然后将其放入浏览器的历史logging中)。

我还利用页面内返回button,使用lasthash数组在页面之间移动用户。 它看起来像这样:

 function goBack() { window.location.hash = window.location.lasthash[window.location.lasthash.length-1]; //blah blah blah window.location.lasthash.pop(); } 

所以这会将用户移回到最后一个散列,并从数组中删除最后一个散列(我现在没有向前的button)。

所以。 如何检测用户是否使用了我的页面内后退button或浏览器button?

起初,我看着window.onbeforeunload ,但无济于事 – 只有在用户要更换页面时才被调用。 这在使用散列导航的单页面应用程序中不会发生。

所以,经过一些挖掘,我看到了试图设置一个标志variables的build议。 在我的情况下这个问题是,我会尝试设置它,但是因为一切都是asynchronous的,它不会总是设置在散列更改中的if语句的时间。 .onMouseDown并不总是在点击中被调用,并且将它添加到onclick将不会足够快地触发它。

这是当我开始看documentwindow之间的区别。 我最后的解决scheme是使用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的检查。 这是因为如果我的数组中没有可用的历史logging,它将返回undefined 。 我用这个来询问用户是否想用window.onbeforeunload事件离开。

因此,简而言之,对于不一定使用页内后退button或数组来存储历史logging的人:

 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 } } 

在那里,你有它。 一个简单的,三部分的方式来检测返回button的使用与页内元素有关的哈希导航。

编辑:

为了确保用户不使用退格来触发返回事件,您还可以包含以下内容(感谢此问题上的@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); 

注意:为了获得最佳结果,您应该只在要实现逻辑的特定页面上加载此代码,以避免出现其他意外问题。

每当当前历史logging条目改变时(用户导航到新的状态),popstate事件被触发。 当用户点击浏览器的“后退/前进”button或者以编程方式调用history.back()history.forward()history.go()方法时,会发生这种情况。

event.state是事件的属性,等于历史状态对象。

对于jQuery语法,将其包装起来(在文档准备就绪后,甚至可以添加监听器):

 (function($) { // Above code here. })(jQuery); 

另请参阅: 页面加载时的window.onpopstate


另请参阅单页面应用程序和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+和类似的兼容。

这是我的看法。 这个假设是,当URL改变但是在检测到的document没有点击时,它就是浏览器(是,或者是转发)。 用户点击2秒后重置,以便在通过Ajax加载内容的页面上进行这项工作:

 (function(window, $) { var anyClick, consoleLog, debug, delay; delay = function(sec, func) { return setTimeout(func, sec * 1000); }; debug = true; anyClick = false; consoleLog = function(type, message) { if (debug) { return console[type](message); } }; $(window.document).click(function() { anyClick = true; consoleLog("info", "clicked"); return delay(2, function() { consoleLog("info", "reset click state"); return anyClick = false; }); }); return window.addEventListener("popstate", function(e) { if (anyClick !== true) { consoleLog("info", "Back clicked"); return window.dataLayer.push({ event: 'analyticsEvent', eventCategory: 'test', eventAction: 'test' }); } }); })(window, jQuery); 

document.mouseover不适用于IE和FireFox。 不过,我试过这个:

 $(document).ready(function () { setInterval(function () { var $sample = $("body"); if ($sample.is(":hover")) { window.innerDocClick = true; } else { window.innerDocClick = false; } }); }); window.onhashchange = function () { if (window.innerDocClick) { //Your own in-page mechanism triggered the hash change } else { //Browser back or forward button was pressed } }; 

这适用于Chrome和IE,而不是FireFox。 仍然努力获得正确的FireFox。 任何简单的方法检测浏览器后退/前进button点击是受欢迎的,不是特别是在JQuery,但也AngularJS或纯JavaScript。

浏览器: 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> 

我一直在为这个需求奋斗了一段时间,并采取了上面的一些解决scheme来实现它。 然而,我偶然发现了一个观察,它似乎可以在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 } } 

让我知道这是否有帮助。 如果我错过了一些东西,我会很乐意去理解。

我尝试了上述选项,但没有一个为我工作。 这是解决scheme

 if(window.event) { if(window.event.clientX < 40 && window.event.clientY < 0) { alert("Browser back button is clicked..."); } else { alert("Browser refresh button is clicked..."); } } 

请参阅此链接http://www.codeproject.com/Articles/696526/Solution-to-Browser-Back-Button-Click-Event-Handli了解更多详情;