【问题标题】:Cross-browser jquery ajax history with window.history.pushState and fallback具有 window.history.pushState 和回退的跨浏览器 jquery ajax 历史记录
【发布时间】:2011-05-14 03:03:48
【问题描述】:

我想以跨浏览器的方式使用 jQuery 和 AJAX 实现导航历史。我的方法是在不支持 window.history.pushState 的浏览器中使用 window.history.pushState 并回退到哈希 URL /#!/url

例如:

<a href="/home">home</a>
<a href="/about">about</a>
<a href="/contact">contact</a>

在支持window.history.pushState的浏览器上,点击这些链接之一应该在不刷新页面的情况下将地址更改为http://domain.com/homehttp://domain.com/about等。当浏览器不支持window.history.pushState时,它应该使用片段标识符,即:http://domain.com/#!/homehttp://domain.com/#!/about


更新:根据此处的反馈,我实现了Ajax SEO (git),它使用 jQuery Address 用于 HTML5 History API,旧浏览器回退到 /#!/url

【问题讨论】:

  • 我在想,如果你需要支持不支持pushState的浏览器,为什么不对所有浏览器使用hash url方法呢?除了“正确性”之外,pushState 还有什么优势可以弥补支持多种方法的复杂性?
  • @DavidHammond,这是github.com/laukstein/ajax-seo直接支持的。

标签: jquery ajax browser-history


【解决方案1】:
// Assuming the path is retreived and stored in a variable 'path'

if (typeof(window.history.pushState) == 'function') {
    window.history.pushState(null, path, path);
} else {
    window.location.hash = '#!' + path;
}

【讨论】:

    【解决方案2】:

    我一直在使用后备哈希 URL 的东西:

    History = History || {};
    History.pathname = null;
    History.previousHash = null;
    History.hashCheckInterval = -1;
    History.stack = [];
    History.initialize = function () {
        if (History.supportsHistoryPushState()) {
            History.pathname = document.location.pathname;
            $(window).bind("popstate", History.onHistoryChanged);
        } else {
            History.hashCheckInterval = setInterval(History.onCheckHash, 200);
        }
    };
    History.supportsHistoryPushState = function () {
        return ("pushState" in window.history) && window.history.pushState !== null;
    };
    History.onCheckHash = function () {
        if (document.location.hash !== History.previousHash) {
            History.navigateToPath(document.location.hash.slice(1));
            History.previousHash = document.location.hash;
        }
    };
    History.pushState = function (url) {
        if (History.supportsHistoryPushState()) {
            window.history.pushState("", "", url);
        } else {
            History.previousHash = url;
            document.location.hash = url;
        }
        History.stack.push(url);
    };
    History.onHistoryChanged = function (event) {
        if (History.supportsHistoryPushState()) {
            if(History.pathname != document.location.pathname){
                History.pathname = null;
                History.navigateToPath(document.location.pathname);
            }
        }
    };
    History.navigateToPath = function(pathname) {
        History.pushState(pathname);
    
        // DO SOME HANDLING OF YOUR PATH HERE
    
    };
    

    你可以将你的点击事件绑定到这个:

    $(function(){
        $("a").click(function(){
            var href = $(this).attr('href');
            History.navigateToPath( href )
            return false;
        });
    });
    

    如果您需要对此示例的更多解释,我会很高兴听到它。


    编辑

    请看我的其他回答。

    【讨论】:

      【解决方案3】:

      我的original answer 已经有一段时间了,我现在建议使用Backbone

      一个实现可以是:

      // First setup a router which will be the responder for URL changes:
      var AppRouter = Backbone.Router.extend({
      
        routes: {
          "*path": "load_content"
        },
      
        load_content: function(path){
          $('#content').load('/' + path);
        }
      
      });
      var appRouter = new AppRouter;
      
      // Then initialize Backbone's history
      Backbone.history.start({pushState: true});
      

      文档摘录:

      要表明您希望在您的应用程序中使用 HTML5 pushState 支持,请使用 Backbone.history.start({pushState: true})。如果您想使用 pushState,但有不支持它的浏览器本身使用整页刷新,您可以将 {hashChange: false} 添加到选项中。

      现在每次调用 Backbone.history.navigate 时,AppRouter 都会执行 AJAX 将路径加载到 #content div 中。

      要使用 AJAX 处理所有链接,您可以使用以下命令:

      $("a").on('click', function(event){
          event.preventDefault();
          Backbone.history.navigate( event.currentTarget.pathname, {trigger: true} )
      });
      

      注意{trigger: true},它会导致路由器中的处理程序被调用(否则仅来自 url 更改)。

      修改示例代码:http://jsfiddle.net/koenpunt/pkAz7/1/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-02
        • 2010-11-01
        • 2015-05-18
        • 1970-01-01
        • 2016-01-09
        • 1970-01-01
        • 2010-10-20
        • 2015-06-14
        相关资源
        最近更新 更多