Im make some ajax calls in my website and im trying to implement the history API to make it so I can navigate it with the browser history. This is the code for the "back button":
$(document).ready(function(){
window.addEventListener("popstate", function(e) {
开发者_StackOverflow社区 //Flag I use to not fire it on the first page load
if (!ajaxhistory)
return;
do_my_ajaxs_things();
}, false);
});
But I have 2 problems
1) When I type the URL in the address bar to load the page for the first time. This also fires the ajax call, which is undesired obviously. Theres no need to ajax, since I have to load the entire page. This one, I have managed to solve it with a flag, but I wonder if theres a more elegant way to do it
2) Lets say I was in "google.com" and the I type my URL "www.mysite.com", then I make an ajax call and I go to "www.mysite.com/contacts". If I press BACK button once, i will go to "www.mysite.com" allright, but if I press BACK again, I will still be in "www.mysite.com", and I find myself I cant go back to google. How could I solve this issue?
All help appreciated. Thanks.
I think that your approach is wrong. You shouldn't need to do AJAX requests each time the user goes back - that's what the state is for, you should have all the relevant data already there. IMHO the logic should be the following:
- If the window loads and
window.history.state
is already set - just apply this state. - Otherwise trigger an AJAX request to retrieve the default state and replace the current state with it.
- Whenever the user navigates to a new "page", trigger an AJAX request to retrieve the new state and push it.
- In your
popstate
handler you should simply apply the state you got inevent.state
, without doing any new AJAX requests.
Here is some example code with a fake loadPage
function, normally you would put your AJAX call there. The applyState
function and state data are also absolutely minimal.
<script type="text/javascript">
window.onload = function()
{
if (window.history.state)
{
applyState(window.history.state);
}
else
{
loadPage(0, function(state, title, loc)
{
window.history.replaceState(state, title, loc);
});
}
window.addEventListener("popstate", function(event)
{
applyState(event.state);
});
}
function goToPage(pageId)
{
loadPage(pageId, function(state, title, loc)
{
window.history.pushState(state, title, loc);
});
}
function loadPage(pageId, callback)
{
window.setTimeout(function()
{
var state = {text: "text" + pageId};
applyState(state);
callback(state, "page " + pageId, "#" + pageId);
}, 100);
}
function applyState(state)
{
document.getElementById("content").textContent = state.text;
}
</script>
<div id="content">
???
</div>
<button onclick="goToPage(1);">1</button>
<button onclick="goToPage(2);">2</button>
<button onclick="goToPage(3);">3</button>
For your first problem, this is really a browser issue. A browser should (in my opinion) never fire the popstate event when the page is loaded initially. I think the best thing you can do is only register the event after the page has been loaded.
History.js is a good library which smoothes out the history API quite a bit. Even if you don't use it they have good documentation about the API here: https://github.com/browserstate/history.js/wiki/The-State-of-the-HTML5-History-API
About your second issue, the browser wil just go to google instead of firing the popstate event for your website. You don't have to worry about that, it's the browsers responsibility
精彩评论