PJAX初体验(主要是利用HTML5 新增API pushState和replaceState+AJAX)

说在前面

       什么是PJAX呢? 站在应用角度的就是既实现了页面无刷新的效果,同时也产生了浏览器的前进和后退,而且url也会变化。 也不是什么新鲜技术,主要是AJAX+html5 pushState和replaceState。   HTML5 为history提供了pushState和replaceState用来在浏览历史记录中添加和修改记录。

       PJAX是在群里看到朋友在聊,孤陋寡闻还没听过这个,平时也没注意观察。附图Github实现了这个效果,当你切换标签时页面局部刷新,浏览URL也会变化。

AJAX载入与浏览器的前进和后退

       众所周知,Ajax可以实现页面的无刷新操作——优点;但是,也会造成另外的问题,无法前进与后退!曾几何时,Gmail似乎借助iframe搞定,如今,HTML5让事情变得如同过家家般简单。

       当执行Ajax操作的时候,往浏览器history中塞入一个地址(使用pushState)(这是无刷新的);于是,返回的时候,通过URL或其他传参,我们就可以还原到Ajax之前的模样。

实例分析

      参考张鑫旭的Demo我自己试了一把。

<a href="/Home/Region?area=pudong">浦东</a>|<a href="/Home/Region?area=baoshan">宝山</a>|<a href="/Home/Region?area=jiading">嘉定</a>
    <ul id="result">

    </ul>
    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script>
        $(function () {
            var eleMenus = $('a').bind('click', function (event) {
                var query = this.href.split('?')[1];
                if (history.pushState && query) {
                    $('#result').empty();
                    $.ajax({
                        url: this.href,
                        type: 'get',
                        dataType: 'json',
                        success: function (data) {
                            
                            $.each(data, function (i, v) {
                                $('<li>' + v.name + ',' + v.price + ',' + v.address + '' + '</li>').appendTo('#result');
                            });
                        }
                    });
                    
                    var title = $(this).text();
                    if (event && /d/.test(event.button)) {
                        history.pushState({ title: title }, title, location.href.split
                            ('?')[0] + '?' + query);
                    }
                }
                return false;
            });

            var fnHashTrigger = function (target) {
                var query = location.href.split("?")[1], eleTarget = target || null;
                if (typeof query == "undefined") {
                    if (eleTarget = eleMenus.get(0)) {
                        // 如果没有查询字符,则使用第一个导航元素的查询字符内容
                        history.replaceState(null, document.title, location.href.split("#")[0] + "?" + eleTarget.href.split("?")[1]) + location.hash;
                        fnHashTrigger(eleTarget);
                    }
                } else {
                    eleMenus.each(function () {
                        if (eleTarget === null && this.href.split("?")[1] === query) {
                            eleTarget = this;
                        }
                    });

                    if (!eleTarget) {
                        // 如果查询序列没有对应的导航菜单,去除查询然后执行回调
                        history.replaceState(null, document.title, location.href.split("?")[0]);
                        fnHashTrigger();
                    } else {
                        $(eleTarget).trigger("click");
                    }
                }
            }

            if (history.pushState) {
                window.addEventListener('popstate', function () {
                    fnHashTrigger();
                });
            }

            fnHashTrigger();
        });
    </script>

实现效果

思路

  • 每次手动点击左侧的菜单,我将Ajax地址的查询内容(?后面的)附在demo HTML页面地址后面,使用history.pushState塞到浏览器历史中。
  • 浏览器的前进与后退,会触发window.onpopstate事件,通过绑定popstate事件,就可以根据当前URL地址中的查询内容让对应的菜单执行Ajax载入,实现Ajax的前进与后退效果。
  • 页面首次载入的时候,如果没有查询地址、或查询地址不匹配,则使用第一个菜单的Ajax地址的查询内容,并使用history.replaceState更改当前的浏览器历史,然后触发Ajax操作

 

参考

http://www.zhangxinxu.com/wordpress/2013/06/html5-history-api-pushstate-replacestate-ajax/

http://www.cnblogs.com/hustskyking/p/history-api-in-html5.html

原文地址:https://www.cnblogs.com/sword-successful/p/5471601.html