简体   繁体   中英

How to capture browser BACK action to keep user in page without refreshing?

I'm trying to control the default BACK action on my PWA because when user press the Mobile Phone's back button it messes up the UX.

For example, when modal is show, back button should close modal and not go back to previous page.

After much research and testing I finally got this working with the following code:

$(window).on('popstate', function (e) {

    let goBack = true;
    if($("#modal_box").is(":visible")) {
        goBack = false;
        $("#modal_box").modal('hide');
    }

    if(goBack == true){
        history.back();
    }else {
        // Stay on the current page.
        history.pushState({}, '');
    }

});

But the problem with this is when the user is scrolled down somewhere middle or bottom of the page the above code makes the view jump back to the top of the page, and it's frustrating the users.

Is there a quick fix for the above code? Or do I need to use different logic since I think the history.pushState is making the page jump up to top no matter what.

UPDATE: Thank you all for comments. I figured a simple way to keep the page from scrolling (or at least visibly scrolling) like how @reynolds suggested... but instead of messing with the scroll state, for some odd reason, using

            history.go(1);

instead of history.pushState({}, '');

works!

What's happening with history.go(1) is that instead of making the page reload to top of page, going "forward" seems to auto scroll to where you were previously, in a very very fast way which the user can't even notice anymore. And this behavior seems to be native in desktop and mobile browsers i've tested on (Firefox, Chrome, Opera). Beautiful!

history.pushstate does not prevent backwards navigation but rather pushes a state to the browser's history stack before the backwards navigation occurs. That said, if you are okay with this, then you could maintain the previous position of the page as Viney said. However, you will need to do so after the page is loaded by loading from the state object.

Capture the scroll position like so:

scrollPos = 0
$(window).scroll(function() {
    scrollPos = $(window).scrollTop();
});

Then, add it to the state:

if(goBack == true){
    history.back();
}else {
    // Stay on the current page.
    history.pushState({ 'scrollPos': scrollPos }, '');
}

Finally, check the state on page load and scroll to scrollPos if available:

const currentState = history.state;

$(window).on('beforeunload', function() {
    if (currentState && currentState.scrollPos) {
        $(window).scrollTop(currentState.scrollPos); 
    }
});

This will, however, also cause the page to scroll to scrollPos on refresh.

Alternatively, if you want to actually prevent back, I recommend you read this post first.

You can preserve the scrollTop value which holds how much window has been scrolled through.

scrollPos = 0
$(window).scroll(function() {
    scrollPos = $(window).scrollTop();
});

Then update that on pushstate

if(goBack == true){
    history.back();
}else {
    // Stay on the current page.
    history.pushState({}, '');
    $(window).scrollTop(scrollPos);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM