Reputation: 2895
The history back function records requests. A page may request itself many times. So when pressing the back button, you might return to the previous request to the same page.
Here is a very simplified example:
Alice.html:
<h1>This is Alice</h1>
<a href="charlie.php">Go to Charlie</a>
Bob.html:
<h1>This is Bob</h1>
<a href="charlie.php">Go to Charlie</a>
Charlie.php:
<h1>This is Charlie</h1>
<p id="output">Here goes the server output</p>
<form method="post">
<input type="hidden" id="somevalue" name="somevalue" value="0">
<button type="button" onclick="window.history.go(-1);">Back</button>
<button type="submit">Calculate</button>
</form>
<script>
// Simulate some server side action
document.getElementById("output").innerHTML = document.getElementById("somevalue").value = "Value = " + Math.random();
</script>
Alice.html and Bob.html both links to Charlie.php. Charlie.php has a form and call itself any number of times, to do some server manipulation of data.
The history back function steps one request back, not one page. To get back to Alice or Bob, the user has to hit the back button the same number of times that she hid the calculate button.
Question: How to step one page back, regardless of the number of requests to Charlie?
Edit: I'm looking for a generic solution for a simple "back up one page" button, without using server side variables.
A HTML5 only solutions is ok.
Upvotes: 2
Views: 2206
Reputation: 2895
This it the solution I'm going with for now. Inspired by myfunkyside.:
I'm using the browser's sessionStorage to store a stack of page names, in order of appearance.
A back (and potentially a forward) function, transverse the stack, invoking window.location.href to call pages.
The stack is maintained with this code included in every page:
// Load or create a history array
var pageHistory = JSON.parse(sessionStorage.pageHistory || '[]');
// Find this page in history
var thisPageIndex = pageHistory.indexOf(window.location.pathname);
// If this page was not in the history, add it to the top of the stack
if( thisPageIndex < 0){
pageHistory.push(window.location.pathname);
thisPageIndex = pageHistory.length -1;
// Wipe the forward history
}else if(thisPageIndex < pageHistory.length -1){
for(; thisPageIndex < pageHistory.length -1;)
pageHistory.pop();
}
// Store history array
sessionStorage.pageHistory = JSON.stringify(pageHistory);
// Back button function
function back(){
if(thisPageIndex > 0 )
window.location.href = pageHistory[thisPageIndex - 1];
}
// Disable back button if this is the first page
if(thisPageIndex < 1)
document.getElementById("backButton").disabled = true;
The button is defined like this:
<button type="button" id="backButton" onclick="back();">Back</button>
Unfortunately this doesn't tie-in with browser history. However it's pure client side javascript, and it works with multiple pages.
It's not as elegant a solution as I had hoped for. I hope someone can provide a better generic solution?
Upvotes: 0
Reputation: 49
The best solution for the information given is to create back links or what they call breadcrumbs linking that person directly to where you want them to go. You can just add a link anywhere guiding them back.
If my answer does not suffice then please explain a little more and it would help to provide a link to your site :). The more detailed you are then the answer will be what you need.
CODE BELOW
<div>
<a href="index.php">Home</a> / <a href="bob.php">Bob</a> / This is Charlie </div>
<h1>This is Charlie</h1>
<p id="output">Here comes the server some output</p>
<form method="post">
<input type="hidden" id="somevalue" name="somevalue" value="0">
<button type="button" onclick="window.history.go(-1);">Back</button>
<button type="submit">Calculate</button>
</form>
<script>
// Simulate some server side action
document.getElementById("output").innerHTML = document.getElementById("somevalue").value = "Value = " + Math.random();
</script>
Upvotes: 1
Reputation: 3950
Instead of navigating through the multiple spoof history items, you might be able to prevent them from being created in the first place, using:
location.replace()
(this will replace the page in the current history item, so no extra click)But since that's probably not possible due to your "server manipulation of data", the code below may offer a solution:
window.onload = function() {
document.getElementById("back").onclick = function() {
sessionStorage.setItem("href",location.href); //store current page into sessionStorage
history.go(-1); //go back one page
};
if (location.href == sessionStorage.getItem("href")) {document.getElementById("back").click();} //if current page is the same as last one, go back one page
else {sessionStorage.removeItem("href");} //clear sessionStorage
};
In the demos below (SO doesn't allow sessionStorage) I had to simulate both "going through the history", and "page load for every history item", so the code looks a little different, using an array and other vars and functions, but the principle should be the same:
codepen: https://codepen.io/anon/pen/OgBgGg?editors=1011
jsfiddle: https://jsfiddle.net/j0ddnboq/2/
Upvotes: 1