Disable HTML5 History Button

I am writing a single page javascript application using the HTML5 history API. The application downloads content via Ajax and internally supports status information on the foreground screen using the stack stack.

I want to enable navigation using the back button, but I never want the forward button to be enabled.

A few quick bits of information:

  • The user should only ever return, never forward
  • Pressing the "Back back" button closes the current screen, on which the user is turned on and reloads the previous one.
  • The project focuses only on the latest version of Chrome, so other versions of browsers are not important.
  • I use only native JavaScript and jQuery, I would like to do this without History.js

When I load a new screen, I run the following line:

history.pushState(screenData, window.document.title, "#"); 

I am communicating with the popstate event via jQuery:

 $(window).bind("popstate", function(event) { if (event.originalEvent.state != null) { // Logic that loads the previous screen using my screen stack } }); 

Managing my application history works, however, when I return, the forward button is on. I need to figure out how to delete data from history in the popstate event.

Can I do this with replaceState? I'm not sure how to do this ...

+14
source share
5 answers

Bad part

To really disable the forward button, you will need to delete the browser history, which is not allowed by all javascript implementations, because this will allow sites to delete the entire history, which would never be in the interests of the user.

Good part

This is a bit complicated, but I think it might work if you want to make a normal story. You can simply use pushState in the pushState event to make your actual page the most recent history entry. I assume that you are processing your story, your window will never be unloaded. This allows you to independently track user history:

 var customHistory = []; 

Press each loaded page history.pushState(screenData, window.document.title, "#"); , as before. Only you add state to your own story:

 history.pushState(screenData, window.document.title, "#"); customHistory.push({data: screenData, title: window.document.title, location: '#'}); 

now, if you have a popstate event, you simply add your own story and click on the topmost entry:

 window.onpopstate = function(e) { var lastEntry = customHistory.pop(); history.pushState(lastEntry.data, lastEntry.title, lastEntry.location); // load the last entry } 

Or in jQuery

 $(window).on('popstate', function(e) { var lastEntry = customHistory.pop(); history.pushState(lastEntry.data, lastEntry.title, lastEntry.location); // load the last entry }); 
+12
source

The accepted answer solves the problem of disabling the "Forward" button, but creates a new annoying problem, the "page you returned to" is inserted into the history in two copies (as indicated in the comments to the answers).

Here's how to solve the "fast forward button" issue and avoid the "re" problem with the "back" button.

 //setup the popstate EventListener that reacts to browser history events window.addEventListener("popstate",function(event){ // In order to remove any "forward"-history (ie disable forward // button), this popstate event history state (having been navigated // back to) must be insert _again_ as a new history state, thereby // making it the new most forwad history state. // This leaves the problem that to have this popstate event history // state to become the new top, it would now be multiple in the history // // Effectively history would be: // * [states before..] -> // * [popstate event.state] -> // * [*newly pushed _duplicate_ of popstate event.state ] // // To remove the annoyance/confusion for the user to have duplicate // history states, meaning it has to be clicked at least twice to go // back, we pursue the strategy of marking the current history state // as "obsolete", as it has been inserted _again_ as to be the most // forward history entry. // // the popstate EventListener will hence have to distinguish 2 cases: // // case A) "popstate event is _not_ an obsolete duplicate"... if( typeof event.state == "object" && event.state.obsolete !== true) { //...so we _firstly_ mark this state as to from now on "obsolete", // which can be done using the history API replaceState method history.replaceState({"obsolete":true},""); // and _secondly_ push this state _one_more_time_ to the history // which will solve the OP desired "disable forward button" issue history.pushState(event.state,""); } // case B: there is the other case that the user clicked "back" and // encounters one of the duplicate history event entries that are // "obsolete" now. if( typeof event.state == "object" && event.state.obsolete === true) { //...in which case we simply go "back" once more history.back() // by this resolving the issue/problem that the user would // be counter-intuively needing to click back multiple times. // > we skip over the obsolete duplicates, that have been the // the result of necessarily pushing a history state to "disable // forward navigation" } },false); 
+5
source

Just use the following jquery to disable the forward button:

  $( document ).ready( function(){ history.pushState(null, document.title, location.href); }); 
+2
source

Transition history is deleted at each user click. To disable forward history, you can simulate this navigation by loading the URL into a hidden iframe (for example, "about: blank") when the page loads.

 var rurl = "about:blank?e=" + Math.random(); window.open(rurl, "clear_fw");//being "clear_fw" the name of the iframe 

Hope this helps.

Edit: This will add an entry to history.back ... In my case, this is not a problem, but consider it.

0
source

Note:

  • This code was tested and worked fine, without any problems, however I would encourage developers to test it again before starting to work with the code.
  • If HTML5 history.replaceState () is used somewhere in your application, the code below may now work.

I created a custom function to disable the forward button.

Here is the code (it does not work with the hash routing strategy):

  <script> (function() { // function called after the DOM has loaded disableForwardButton(); })(); function disableForwardButton() { var flag, loop = false; window.addEventListener('popstate', function(event) { if (flag) { if (history.state && history.state.hasOwnProperty('page')) { loop = true; history.go(-1); } else { loop = false; history.go(-1); } } else { history.pushState({ page: true }, null, null ); } flag = loop ? true : !flag; }); window.onclick = function(event) { flag = false; }; } </script> 

As Redrif noted in the comments on the accepted answer, the problem is that you need to double-click the "Back" button to return to the page, which is tedious and impractical.

Code Explanation: Each time you press the back button, you need to create an additional history element so that the current page you are on points to a newly created history page. Thus, there is no page to go forward because pushState is the last state (imagine it as the last element in the array), so your forward button will always be disabled.

The reason you had to enter a loop variable is because you might have a script where you go back to a specific page and pushState code appears that creates the last element of the story, and instead, going back, you select the click for some, follow the link back to the previous page, which now creates an additional element of the story. In other words, you have something like this:

[page1, page2, page2, page2]

Now, when you turn on page2 (index 3 element) and press the back button again, you will again get index 1 element on page2 , and you don’t need it. Remember that you may have an array of x page2 elements, therefore, to resolve this particular case, a false loop variable was introduced, with which you go from page2 to page 1 no matter how many page2 elements page2 are in the array.

0
source

Source: https://habr.com/ru/post/920823/


All Articles