Запуск функции jQuery ajax, когда пользователь нажимает кнопки назад или вперед

#jquery

#jquery

Вопрос:

У меня есть следующий пример, где, когда пользователь нажимает на строку навигации, он загружает некоторый контент с помощью AJAX, а также обновляет URL и заголовок с помощью jquery history.js https://github.com/browserstate/History.js плагин для создания истории HTML5.

  ajaxNav: function () {

        $('#uiTabs li a, .ajax').live('click', function (e) {

            e.preventDefault();

            $('<div id="uiLoader"></div>').appendTo('body').hide().fadeIn();

            var url = $(this).attr('href');

            var bodyid = $(this).data('body');

            $.ajax({
                url: url,
                timeout: 5000,
                success: function (responseHtml) {

                    isAjaxNav = true;

                    var content = $(responseHtml).find('#ajax-nav-html');

                    $('.uiContent > .uiPadding').html(content.hide().fadeIn('slow'));

                    History.pushState(null, $(responseHtml).filter('title').text(), url);

                    $('body').attr('id', bodyid);
                    $('#uiLoader').fadeOut(function () { $('#uiLoader').remove() });

                },
                error: function (jqXHR, textStatus, errorThrown) {
                    if (textStatus == 'timeout') {
                        uiModal.errorTimeoutModal(jqXHR, textStatus, errorThrown);
                    } else if (jqXHR.status == "500") {
                        uiModal.error500Modal(jqXHR, textStatus, errorThrown);
                    } else if (jqXHR.status == "404") {
                        uiModal.error404Modal(jqXHR, textStatus, errorThrown);
                    } else {
                        uiModal.errorUnknownModal(jqXHR, textStatus, errorThrown);
                    }

                    $('#uiLoader').fadeOut(function () { $('#uiLoader').remove() });

                }
            });

        });

    },
  

Однако, когда пользователь нажимает кнопки «Назад» или «Вперед», это изменит URL и заголовок (поскольку плагин поддерживает это нормально), но содержимое не изменится! Как бы мне определить это, чтобы я мог прочитать новый URL, используя, например, $('location').att('pathname'); , а затем выполнить еще несколько ajax?

Так, например:

 //IF back button or forward button clicked or relevant function e.g backspace
$(<!-- ? -->).click(function() {

// Get the current url when the back or forward button was clicked
var url = $('location').att('pathname');

$.ajax({
                url: url,
                timeout: 5000,
                success: function (responseHtml) {

                    isAjaxNav = true;

                    var content = $(responseHtml).find('#ajax-nav-html');

                    $('.uiContent > .uiPadding').html(content.hide().fadeIn('slow'));

                    History.pushState(null, $(responseHtml).filter('title').text(), url);

                    $('body').attr('id', bodyid);
                    $('#uiLoader').fadeOut(function () { $('#uiLoader').remove() });

                },
                error: function (jqXHR, textStatus, errorThrown) {
                    if (textStatus == 'timeout') {
                        uiModal.errorTimeoutModal(jqXHR, textStatus, errorThrown);
                    } else if (jqXHR.status == "500") {
                        uiModal.error500Modal(jqXHR, textStatus, errorThrown);
                    } else if (jqXHR.status == "404") {
                        uiModal.error404Modal(jqXHR, textStatus, errorThrown);
                    } else {
                        uiModal.errorUnknownModal(jqXHR, textStatus, errorThrown);
                    }

                    $('#uiLoader').fadeOut(function () { $('#uiLoader').remove() });

                }
            });
});
  

Комментарии:

1. Вы не проявляете усилий, но, к сожалению, я не могу понизить ваш голос, как вы сделали со мной. Ответ заключается в history.js. Прочитайте документацию еще раз. Автор предоставляет полную версию с комментариями.

2. Действительно? Можете ли вы показать ссылку, поскольку я просмотрел документацию, и я ничего не вижу об обработке этого… Я видел History.back() функцию, но это НЕ то, что мне здесь нужно!

Ответ №1:

Вам необходимо подключиться к window.onpopstate событию:

 $(window).on("popstate", function (evt) { // use bind() for jQuery < 1.7
    /* ... */
});
  

Рабочая демонстрация: http://jsfiddle.net/AndyE/CZwQB (использует методы DOM вместо jQuery)

Комментарии:

1. Также, когда состояние изменяется, как оно узнает, что нужно изменить? поскольку у меня есть другие вызовы ajax на странице, которые также будут классифицироваться как statechange, поэтому он будет вызывать функцию, когда она не нужна! а также вызывайте ее при вызове первой функции, которую я опубликовал. Таким образом, мы в конечном итоге вызывали ajax дважды и при любых изменениях состояния!

2. @Cameron: вы можете сделать это, проанализировав текущий URL-адрес в popstate обработчике событий, или вы можете отправить данные, возвращенные вашими предыдущими вызовами AJAX, при вашем вызове pushState и повторно обработать их в popstate событии путем доступа event.state .

3. @Cameron: У меня недостаточно времени, чтобы написать пример AJAX, но я могу заверить вас, что он не слишком отличается от примера, который я только что добавил к своему сообщению. Пока вы передаете свои данные AJAX в pushState() , это должно работать очень похоже.

4. Спасибо за пример, но проблема в том, что функция запускается сразу, а не только когда пользователь нажимает кнопки «Назад» или «Вперед».

5. @Cameron: вы говорите о моем примере или о своем коде? В моем примере вы можете предотвратить это, удалив часть, которая проверяет window.location.search содержимое в верхней части кода.