I'm having a weird issue with pushState/popstate where it seems my initial page is saved twice.
It's a bit hard to explain without an example.
something like this:
As you can see, I need to press the back button twice to get me back to www.bing.com when it should have only needed 1.
a short explanation of my page (code is at the bottom of the page):
when the page loads, initial list for the dropdown selection is retrieved via AJAX and populates the select tag.
user has option to click on 3 links which determine the contents of the dropdown selection. Example: If I click on Option B link, this fires the same AJAX from step1 but only retrieves data suitable for Option B.
The user makes a selection from the dropdown and presses search. This triggers another AJAX function which retrieves the relevant data and displays the formatted information inside the mysearchresults div.
I tried playing around with placement (e.g. before or after AJAX call) of pushState and the placement now seems the one that give me the least problem. Although I do encounter the issue I mentioned above.
Here's my code. I had to strip out a lot of code/functions to make it short and readable but please be assured the AJAX calls/data display are working.
<div id="content">
<p>
<a class="coursetype" href="#" data-type="B">Option B</a>
| <a class="coursetype" href="#" data-type="H">Option H</a>
| <a class="coursetype" href="#" data-type="BG">Option BG</a>
</p>
<form id="myform">
<label class="formlabel" for="course">Select your course</label>
<br /><select id="course" name="course"></select>
<button id="searchbutton" type="button">Search Me</button>
</form>
<div id="mysearchresults"></div>
</div>
$(document).ready(function() {
var onClickCourseTypeHandler = function(event) {
event.preventDefault();
getCourses({ type:$(event.target).data("type") });
window.history.pushState({ html:$("#content").html(), coursecode:$("#coursecode").val() }, "", main?type="+pagevars.type);
}
var onClicksearchbuttonHandler = function(event) {
if ($("#coursecode").val().length > 0) {
searchDB({ course:$("#course").val() });
window.history.pushState({ html:$("#content").html(), coursecode:$("#coursecode").val() }, "", "/main?&course="+$("#course").val());
}
};
$(document).on("click", ".coursetype", onClickCourseTypeHandler);
$(document).on("click", "#searchbutton", onClicksearchbuttonHandler);
try {
window.addEventListener("popstate", function(event) {
if (event.state) {
$("#content").html(event.state.html);
if (event.state.coursecode.length > 0) {
if ($("#course option[value='" + event.state.course + "']").length > 0) {
$("#course").val(event.state.course);
} else {
$("#course option:first-child").attr("selected", "selected");
}
}
}
});
} catch(exception) {
}
onLoad();
function onLoad() {
getCourses({ type:"" });
window.history.pushState({ html:$("#content").html(), course:dbvars.course }, "", "/main");
}
function searchDB(parameters) {
$.ajax({
url: baseurl+"/searchDB"
, cache: false
, dataType: "json"
, data: { format:"json", course:parameters.course }
, success: function(data, status) {
parameters.data = data;
displaySearchResults(parameters);
}
});
}
function getCourses(parameters) {
if (typeof(parameters.cacheflag) === "undefined") { parameters.cacheflag = false; };
$.ajax({
url: baseurl+"/getCourses"
, cache: parameters.cacheflag
, dataType: "json"
, data: { format:"json", coursetype:parameters.type }
, success: function(data, status) {
parameters.data = data;
populateCourses(parameters);
}
});
}
});
But this function is not intended to reload the browser. All the function does, is to add (push) a new "state" onto the browser history, so that in future, the user will be able to return to this state that the web-page is now in.
The popstate event will be triggered by doing a browser action such as a click on the back or forward button (or calling history. back() or history. forward() in JavaScript). Browsers tend to handle the popstate event differently on page load.
replaceState() operates exactly like history. pushState() except that replaceState() modifies the current history entry instead of creating a new one. replaceState() is particularly useful when you want to update the state object or URL of the current history entry in response to some user action.
The history. pushState() method allows you to add an entry to the web browser's session history stack.
When you load your page, it gets added to the History, so when you do history.pushState
it's added a second time.
Try replacing history.pushState
with history.replaceState
in the onload function.
I noticed your using hashes (#) in your hrefs. Try changing the hashes (#) in your a hrefs to Javascript:void(0).
Javascript:void(0);
Hashes(#) in href will have an effect your pushState/popState.
Pass an object literal to pushState() on page load. This way you can always go back to your first created pushState.
Add to DOM ready
var obj = { html: '', coursecode: '' };
try {
window.history.pushState({
html: $("#content").html(),
coursecode: $("#coursecode").val()
}, 'just content or variable', window.location.href);
} catch (e) {
console.log(e);
}
In your eventhandler to push state:
var onClicksearchbuttonHandler = function(event) {
if ($("#coursecode").val().length > 0) {
searchDB({ course:$("#course").val() });
obj.html = $("#content").html();
obj.coursecode = $("#coursecode").val();
window.history.pushState(obj, "", "/main?&course="+$("#course").val());
}
};
When going back to your original pushstate:
$(window).on('popstate', function (ev) {
var originalState = ev.originalEvent.state || obj.html;
if (!originalState) {
// no history
// do something
return;
} else {
// do something
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With