使用pushState和popstate优化ajax

现在越来越多的网站都会使用到ajax,ajax优点有很多。操作方便、刷新速度快、节省流量、用户体验好等等...但是,ajax使用的缺点也是显而易见的,首先ajax请求并不会在history中添加记录状态。这样,当用户习惯性的点击了后退或前进按钮的时候,这时呈现的页面,可能就和用户期望得到的结果差之千里了

当然这可以通过使用#改变哈希值的方式来向history添加记录状态,来实现同浏览器后退前进操作友好兼容。但是,这样,却又影响了搜索引擎的收录,搜索引擎是不去理会#后面的东西的。哎,为什么总是这样子不完美呀,纠结死了,到底有没有完美一点的解决方案呀

先来个demo看看吧,猛戳这里,只是这只适用于高富帅浏览器,IE10以下那些奇葩臭屌丝先不鸟他们。怎么样,还不错吧,是不是心痒痒的想知道怎么实现的,那我就揭晓答案了^_^

window.history.pushState(object, title, url);

上面这行命令,可以让地址栏出现新的URL,并且向history添加记录状态,可用于后退和前进操作。history对象的pushState方法接受三个参数,新的URL就是第三个参数,前两个参数都可以是nul。接着,使用ajax去获取相应的html,然后再追加到当前页面,就行了,是不是很简单,还是看代码吧
html代码

@if (Request.IsAjaxRequest())   //这里是 ASP.NET MVC 4 的写法。当页面是通过ajax请求的时候,返回局部页面。否则返回整个页面,当搜索引擎来抓取的时候,返回的是整个页面
{<div>
    <a href="page1">go to page1</a><br />
    <br />
    现在是main页面,注意观察地址栏已经变为main,页面也跳转到main,但是音乐却没有中断
    <br />
    <br />
    <a href="page2">go to page2</a></div>
}
else
{<!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>main</title>
    </head>
    <body>
        <audio autoplay="autoplay" controls="controls" loop="loop" src="http://www.inkcn.com/2010/tkzc.mp3">
        </audio>
        <div id="container">
            <a href="page1">go to page1</a><br />
            <br />
            现在是main页面,注意观察地址栏
            <br />
            <br />
            <a href="page2">go to page2</a>
        </div>
    </body>
    </html>
}
if (!!(window.history && window.history.pushState)) {
    var container = $("#container");
    var loadPage = function (url, isPush) {     //加载页面的方法,isPush是用来区别是否需要调用pushState方法
        if (isPush)
            window.history.pushState(null, null, url);    //向history添加一个记录状态
        $.get(url, function (result) {
            container.html(result);
        });
    }

    container.on("click", "a", function (e) {     //为a标签注册事件,并阻止其默认行为
        loadPage(this.href, true);
        e.preventDefault();
    });
    
    //需要注意的是,当页面第一次加载,在onload之后,Chrome和Safari浏览器(Webkit核心)会触发popstate事件,而Firefox和IE浏览器不会
    $(window).on("popstate", function (e) {   //为window绑定popstate事件,用于监控浏览器触发后退和前进操作
        loadPage(location.href, false);              //当前进后退操作触发的时候,再去加载当前url页面
    });
} else {
    alert("抱歉,您的浏览器不支持");
}

另外两个页面,代码也和这类似,就不全粘出来了。请认真看哟,代码很简单,相信你很容易就能看懂,当然,这样,就解决了浏览器前进后退的问题,也解决了搜索引擎的问题
等等,你说什么?屌丝IE不支持?oh my god,我们一起祈祷屌丝快些灭亡吧