Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
390 views
in Technique[技术] by (71.8m points)

javascript - 如何检测浏览器后退按钮事件-跨浏览器(How to Detect Browser Back Button event - Cross Browser)

How do you definitively detect whether or not the user has pressed the back button in the browser?

(您如何确定用户是否按下浏览器中的“后退”按钮?)

How do you enforce the use of an in-page back button inside a single page web application using a #URL system?

(您如何使用#URL系统在单页Web应用程序中强制使用页内后退按钮?)

Why on earth don't browser back buttons fire their own events!?

(到底为什么浏览器后退按钮不触发自己的事件!?)

  ask by Xarus translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

(Note: As per Sharky's feedback, I've included code to detect backspaces)

((注意:根据Sharky的反馈,我提供了用于检测退格的代码))

So, I've seen these questions frequently on SO, and have recently run into the issue of controlling back button functionality myself.

(因此,我经常在SO上看到这些问题,并且最近遇到了自己控制后退按钮功能的问题。)

After a few days of searching for the best solution for my application (Single-Page with Hash Navigation), I've come up with a simple, cross-browser, library-less system for detecting the back button.

(在为我的应用程序寻找最佳解决方案(带哈希导航的单页)几天后,我提出了一个简单的,跨浏览器,无库的系统来检测后退按钮。)

Most people recommend using:

(大多数人建议使用:)

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

However, this function will also be called when a user uses on in-page element that changes the location hash.

(但是,当用户使用更改位置哈希值的页内元素时,也会调用此函数。)

Not the best user experience when your user clicks and the page goes backwards or forwards.

(当用户单击并且页面向后或向前移动时,并不是最佳的用户体验。)

To give you a general outline of my system, I'm filling up an array with previous hashes as my user moves through the interface.

(为了让您大致了解我的系统,我在用户移动界面时用以前的哈希填充了一个数组。)

It looks something like this:

(看起来像这样:)

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

Pretty straight forward.

(非常简单。)

I do this to ensure cross-browser support, as well as support for older browsers.

(我这样做是为了确保跨浏览器支持以及对较旧浏览器的支持。)

Simply pass the new hash to the function, and it'll store it for you and then change the hash (which is then put into the browser's history).

(只需将新的哈希传递给函数,它将为您存储该哈希,然后更改哈希(然后将其放入浏览器的历史记录中)。)

I also utilise an in-page back button that moves the user between pages using the lasthash array.

(我还利用了一个页面内后退按钮,该按钮可使用lasthash数组在页面之间移动用户。)

It looks like this:

(看起来像这样:)

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

So this will move the user back to the last hash, and remove that last hash from the array (I have no forward button right now).

(因此,这会将用户移回最后一个哈希,并从数组中删除最后一个哈希(我现在没有前进按钮)。)

So.

(所以。)

How do I detect whether or not a user has used my in-page back button, or the browser button?

(如何检测用户是否使用了页面内后退按钮或浏览器按钮?)

At first I looked at window.onbeforeunload , but to no avail - that is only called if the user is going to change pages.

(最初,我看了window.onbeforeunload ,但无济于事-仅在用户要更改页面时才调用。)

This does not happen in a single-page-application using hash navigation.

(在使用哈希导航的单页应用程序中不会发生这种情况。)

So, after some more digging, I saw recommendations for trying to set a flag variable.

(因此,经过进一步的挖掘,我看到了有关尝试设置标志变量的建议。)

The issue with this in my case, is that I would try to set it, but as everything is asynchronous, it wouldn't always be set in time for the if statement in the hash change.

(在我的案例中,这个问题是我会尝试设置它,但是由于所有内容都是异步的,因此并不总是及时为哈希更改中的if语句设置它。)

.onMouseDown wasn't always called in click, and adding it to an onclick wouldn't ever trigger it fast enough.

(.onMouseDown并非总是在click中调用,将其添加到onclick不会足够快地触发它。)

This is when I started to look at the difference between document , and window .

(这是我开始查看documentwindow之间的区别的时候。)

My final solution was to set the flag using document.onmouseover , and disable it using document.onmouseleave .

(我的最终解决方案是使用document.onmouseover设置标志,并使用document.onmouseleave禁用它。)

What happens is that while the user's mouse is inside the document area (read: the rendered page, but excluding the browser frame), my boolean is set to true .

(发生的是,当用户的鼠标位于文档区域内(读取:呈现的页面,但不包括浏览器框架)时,我的布尔值设置为true 。)

As soon as the mouse leaves the document area, the boolean flips to false .

(鼠标离开文档区域后,布尔值立即翻转为false 。)

This way, I can change my window.onhashchange to:

(这样,我可以将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();
        }
    }
}

You'll note the check for #undefined .

(您会注意到对#undefined的检查。)

This is because if there is no history available in my array, it returns undefined .

(这是因为如果我的数组中没有可用的历史记录,它将返回undefined 。)

I use this to ask the user if they want to leave using a window.onbeforeunload event.

(我用它来询问用户是否要使用window.onbeforeunload事件离开。)

So, in short, and for people that aren't necessarily using an in-page back button or an array to store the history:

(简而言之,对于不一定使用页内后退按钮或数组来存储历史记录的用户:)

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

And there you have it.

(那里有它。)

a simple, three-part way to detect back button usage vs in-page elements with regards to hash navigation.

(一种简单的,由三部分组成的方法,用于检测关于哈希导航的后退按钮使用率和页内元素。)

EDIT:

(编辑:)

To ensure that the user doesn't use backspace to trigger the back event, you can also include the following (Thanks to @thetoolman on this Question ):

(为了确保用户不使用退格键触发回事件,您还可以包括以下(2009年,由于@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();
            }
        }
    });
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...