总是在github down点东西,github整个界面做的不错,体验也很好~对于其中的源代码滑动的特效最为喜欢了~刚开始以为这个只是普通的ajax请求效果,但是发现这个特效能够导致浏览器地址栏跟随变化,并且再点击前进后退按钮后又可以将代码滑回滑出~~于是乎就来研究下吧~

一、通过锚点Hash实现:
在这方面其实国内很早就有做了,比如淘宝画报,通过的是在地址栏后面加#锚点实现的,浏览器是可以识别锚点为单位的历史记录的。但不是说页面本身有这个锚点,锚点的Hash只是起到一个引导浏览器将这次的记录推入历史记录栈顶的作用。
来做一个小小的demo:
Tab1
Tab2
1
2
一个很简单的Tab切换如果一般情况下就直接:
$("#tab1_header").click(function() {
$("#tab2").hide();
$("#tab1").show();
});
$("#tab2_header").click(function() {
$("#tab1").hide();
$("#tab2").show();
});但假如点击到tab2时想通过后退按钮退到tab1时就不行了,假如刷新的话浏览器的行为完全不是出于用户的想法,这样的话,我们可以加入#锚点来模拟新页面,为什么要说模拟呢,假如直接通过js改变window.location浏览器会重新加载页面,但加#就不会重新加载并且能保存在历史中。JS通过window.location.hash来控制URL后面的锚点#。
我们把代码改为这样:
$(function(){
showTab();
$(window).bind('hashchange', function(e){
showTab();
});
$("#tab1_header").click(showTab1);
$("#tab2_header").click(showTab2);
});
function showTab() {
if (window.location.hash == "#tab2"){
showTab2();
} else {
showTab1();
}
}
function showTab1() {
$("#tab2").hide();
$("#tab1").show();
window.location.hash = "#tab1";
};
function showTab2() {
$("#tab1").hide();
$("#tab2").show();
window.location.hash = "#tab2";
};加上window.location.hash = "#tab1"这一段代码就行了,在点击tab后,地址栏后面就会加上#tab1,点击tab2后就会改成#tab2,当浏览器检测到url变化时就会触发hashchange这一事件,就是用户在点击后退时能够得到的事件就能够通过window.location.hash进行判断并进行ajax操作了,但是haschange这个事件并不是每个浏览器都有的,只有现代高级浏览器才有,所以在低级的浏览器中需要用轮询来检测URL是否在变化,这个这里就不具体说了。
二、通过HTML5加强型的History对象实现(类Pjax)
可以通过window.history.pushState这个方法无刷新的更新浏览器地址栏,这个方法在更新地址栏的同时将地址压入历史记录堆栈里,而要取出这个栈顶页面则可以用popstate这个事件来捕获~
来模拟一下github的环境,github中每个url是对应一个完整的实际页面的,所以在ajax请求页面时需要异步获取target页面中指定id容器中的内容:
比如有这样两个页面:
index.html
index
second.html
second
假如用同步的http请求打开的话完全是两个页面,两个页面加入很多地方一样的话我们完全可以用这种方法来实现ajax请求变更DOM,我在这里加了语句通过它的变化能得知是否取自两个http请求,局
部的ajax请求是不会改变这个时间显示的。
$(function() {
var state = {
title: "index",
url: "index.html"
};
$("#cn").click(function() {
window.history.pushState(state, "index", "second.html");
var $self = $(this);
$.ajax({
url: "second.html",
dataType: "html",
complete: function(jqXHR, status, responseText) {
responseText = jqXHR.responseText;
if (jqXHR.isResolved()) {
jqXHR.done(function(r) {
responseText = r;
});
$self.html($("").append(responseText.replace(/









