Learning the history API
I am trying to learn the history API following the write-up at http://diveintohtml5.info/history.html. My simple test web page is as follows
<body>
<ul>
<li><a class="test" id="foo" href="/?a=foo">This is foo</a></li>
<li><a class="test" id="bar" href="/?a=bar">This is bar</a></li>
<li><a class="test" id="baz" href="/?a=baz">This is baz</a></li>
<li><a class="test" id="qux" href="/?a=qux">This is qux</a></li>
</ul>
<script type="text/javascript">
//<![CDATA[
var A = {
"test" : function(loc) {
$.ajax({
url : loc,
type : "GET",
data : "",
dataType: "json",
error : function() { alert("Error"); },
success : function(res) {
var divs = ["foo", "bar", "baz", "qux"];
for (var i = 0; i <= divs.length; i++) {
$("#" + divs[i]).html( res[ divs[i] ] );
}
history.pushState(null, null, loc);
}
});
},
"setupClicks" : function() {
$(".test").click(function() {
PK.test($(this).attr("href"));
return false;
});
}
};
$(document).ready(function() {
A.setupClicks();
window.setTimeout(function() {
window.addEventListener("popstate", function(e) {
A.test(location.href);
}, false);
}, 1);
});
//]]>
</script>
</body>
Almost everything works 开发者_C百科well. When I click on a link, the URL is changed correctly, the new page fragments are fetched from the server via ajax, and inserted in the correct location.
What doesn't work well is the browser back button. Or, rather, it works the first time, and not after that. So, if I click on "foo" and then "bar" and then "baz" and then "qux" and then I hit the browser back button, I go back from "qux" to "baz". But, after that, no matter how many times I click on the browser back button, it remains on "baz" instead of backtracking to "bar" and then to "foo".
What am I doing wrong? (I don't want suggestions for jQuery plugins at this point. I simply want to understand the error of my ways).
figured out why my code was not working, and also figured out a hacky workaround. But, am still curious to learn better ways to do this --
<script type="text/javascript">
//<![CDATA[
var A = {
"test" : function(loc) {
$.ajax({
..
success : function(res) {
..
**** > history.pushState(null, null, loc);
}
});
}
};
$(document).ready(function() {
window.setTimeout(function() {
window.addEventListener("popstate", function(e) {
++++ > A.test(location.href);
}, false);
}, 1);
});
//]]>
</script>
In the code above, everytime history.pushState()
was called (line marked **), the location was correctly pushed into the stack. When popstate
was called as a result of pressing the browser back button (line marked ++++), it worked fine the first time, but in doing so, it once again called history.pushState()
pushing the new loc in the stack again in a circular fashion. So, if I moved from A -> B -> C, I had A, B and C in the stack. When I pressed back, I went back to B, but in doing so, I pushed B into the stack again. Pressing back now meant that I would once again go back to B, and be caught in this loop.
I modified the above code to as below, and now it works
<script type="text/javascript">
//<![CDATA[
var A = {
"test" : function(loc, how) {
$.ajax({
..
success : function(res) {
..
if (how !== "back") {
**** > history.pushState(null, null, loc);
}
});
}
};
$(document).ready(function() {
window.setTimeout(function() {
window.addEventListener("popstate", function(e) {
++++ > A.test(location.href, "back");
}, false);
}, 1);
});
//]]>
</script>
How can I do the above better?
精彩评论