Подтвердить что ты не робот

Кросс-браузер jQuery ajax history с window.history.pushState и резервное копирование

Я хочу реализовать историю навигации, используя jQuery и AJAX в кросс-браузере. Мой подход состоит в том, чтобы использовать window.history.pushState и вернуться к хэш-адресу url /#!/url в браузерах, которые не поддерживают window.history.pushState.

Например:

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

В браузерах, поддерживающих window.history.pushState, нажатие на одну из этих ссылок должно изменить адрес без обновления страницы до http://domain.com/home, http://domain.com/about и т.д. Когда браузер не поддерживает window.history.pushState, он должен использовать идентификатор фрагмента, то есть: http://domain.com/#!/home, <а3 > .


Обновление: на основе отзывов здесь я реализовал Ajax SEO (git), который использует jQuery Address для API истории HTML5 со старым возвратом браузера на /#!/url.

4b9b3361

Ответ 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

Что-то, что я использовал с возвратными хеш-адресами:

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

Прошло некоторое время с моего оригинального ответа, и теперь я предлагаю использовать 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 history
Backbone.history.start({pushState: true});

Выдержка из документации:

Чтобы указать, что вы хотите использовать поддержку HTML5 pushState в своем приложении, используйте Backbone.history.start({pushState: true}). Если вы хотите использовать pushState, но у браузеров, которые его не поддерживают, вместо этого воспользуйтесь полным обновлением страницы, вы можете добавить {hashChange: false} к параметрам.

И теперь каждый раз, когда вызывается Backbone.history.navigate, AppRouter будет выполнять загрузку AJAX пути в div #content.

Чтобы обрабатывать все ссылки с помощью 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/