Вопрос по popstate, jquery, pushstate, html5, history.js – pushState () и popState (): манипулирование историей браузеров

6

Я работаю над небольшим проектом, в котором я хочу создать сайт в стиле Ajax. Контент загружен с помощью jQueryload(), Как некоторые из вас знают, недостатком этого является то, что URL не изменяется в соответствии с отображаемым контентом. Чтобы сделать эту работу вы можете использоватьpushState(), Поскольку это не поддерживается кросс-браузер, я использовал плагинhistory.js.

Это работает довольно хорошо, но проблема в том, что мои кнопки «назад» и «вперед» не работают должным образом, и я понятия не имею, что я делаю неправильно. URL-адрес меняется правильно, и содержание также, но заголовок не меняется вообще. Под заголовком я подразумеваю то, что отображается как заголовок окна (или вкладки) окна браузера. То есть<title> загруженной страницы ИЛИ атрибут заголовка ссылки, которая ссылается на эту страницу (они одинаковы). Я думаю, что это связано с тем, что я называю только часть страницы, чей заголовок мне нужен (т. Е. Путем добавления#content кload()). Я все еще хочу заголовок этой страницы, хотя. Вот контрольный пример того, что у меня есть до сих пор. (Больше не доступно с 28 декабря 2013 года.) Файл jQuery:

$(document).ready(function () {
    var firstLink = $("ul > li:first-child > a");
    var menuLink = $("ul > li > a");
    var firstLoadedHtml = firstLink.attr("href") + " #content";

    $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast");
    firstLink.addClass("active");   

    menuLink.click(function(e) {
        history.pushState(null, null, this.href);

        e.preventDefault();
        e.stopImmediatePropagation();

        var CurLink = $(this);
        var newLoadedHtml = CurLink.attr("href") + " #content";
        var oldSection = $(".contentPage");

        $("#sectionContainer").hide().load(newLoadedHtml).fadeIn("fast");
        menuLink.removeClass("active");
        CurLink.addClass("active");
    });

    $(window).bind('popstate', function() {
            var returnLocation = history.location || document.location;

            $('#sectionContainer').load(returnLocation + "#content");
    });
});

Я также отметил, что при возврате к базовой странице (то есть / sectionLoaderTest /) она некоторое время очищается и только через некоторое время загружается содержимое первой страницы. Есть ли способ оптимизировать это?

Кроме того, я использую jQuery для добавления активного класса к ссылке, по которой щелкнули. Как я могу убедиться, что это меняется в соответствии с историей? Чтобы правильная ссылка выделялась при переходе пользователя назад?

Итак, три вопроса:

Get the title working when going forward and backward Optimize the load time of the mainpage Fix the active-class when going forward and backward

Вся помощь приветствуется!

NOTE 1: Я хотел бы опираться на history.js и мой собственный скрипт, и поэтому поддерживаю поддержку< HTML5 браузеры. Я бы предпочел это, потому что: 1. Я знаю, что это должно работать, просто что-то идет не так. 2. Было бы сэкономлено время, если бы я мог увидеть одно решение и реализовать его в сценарии, который я уже написал, вместо того, чтобы выяснять совершенно новый сценарий.

NOTE 2: Щедрость будет дана только ему или ей, кто может ответить на все мои вопросы (3)!

Вы все еще не правы, посмотрите пример такого здесьstackoverflow.com/questions/6622449/… devote
Под заголовком я подразумеваю то, что отображается как заголовок окна (или вкладки) окна браузера. То есть & lt; title & gt; загруженной страницы ИЛИ атрибут заголовка ссылки, которая ссылается на эту страницу (они одинаковы). Bram Vanroy
Мой комментарий указывает на вашу ошибку, как правильно выбрать методы обработки события. Неверный метод перехвата события, которое вы опубликовали, удалите его из метода, который срабатывает при нажатии. devote
Добавлен history.js, все еще не работает Bram Vanroy
Ваш комментарий не очень полезен. Мне не нужно реализовывать history.js (пока), я просто пытаюсь понять, что сейчас делает pushState. Я хочу решить эту проблему. Bram Vanroy

Ваш Ответ

2   ответа
11

Answer 1 - Get the title working when going forward and backward

Насколько я понял, вы хотите изменить заголовок документа HTML из ссылки загружается в div. Когда вы загружаете файл в div через jQuery.load Вы просто вставляете полный текст ответа после ajax-запроса. Таким образом, со всеми вещами, которые не должны быть в div какtitle или жеmeta тег. Однако название текущего документа (http://bramvanroy.be/sectionLoaderTest/index.html) определяется вtitle который находится внутриhead тег, а не вtitle пометьте внутри div, чтобы название документа не менялось.

So how can I fix it?

Хороший вопрос, потому чтоtitle элемент внутриdiv элемент недействителен, большинство браузеров удалит его, поэтому вы не можете просто использовать это:

document.title = $("#sectionContainer title").text();

посколькуtitle элемент может не существовать

Так что нам нужен прямой ответ от jQuery.load функция. Я могу получить это, добавив аргумент обратного вызова в функцию:

$("#sectionContainer")
    .hide()
    .load(newLoadedHtml, function(responseText) {
        document.title = $(responseText).filter("title").text();
    })
    .fadeIn("fast");

Что вы можете не понять, почему я использую.filter а не.find функция. Это потому, что JQuery это своего рода парсингhtml, head а такжеbody теги из HTML, но не удаляя там дочерние элементы.

Answer 2 - Optimize the load time of the mainpage

Документ загружается сверху вниз.

Итак, сначала нужно загрузить CSS, JavaScript и т. Д., А затем основной документ. Поскольку jQuery всегда ожидает документа, прежде чем он его выполнит, было бы очень плохой идеей поместить все вашиscript элементы прямо перед концом тела, так что ваш HTML может быть загружен раньше.

Кстати, у меня просто была эта проблема в первый раз после того, как все было кэшировано, и документ загружался очень быстро.

Answer 3 - Fix the active-class when going forward and backward

Я бы сказал, что цикл черезhref атрибутыa элементы и сравнить его с данными изHistory.getState(), Должно быть легко.

You did some mistakes in your code - Your fixed code:

Вы добавили хеш#content ко всем URL-адресам ... это не имеет смысла, и он снова будет удален jQuery:https://github.com/jquery/jquery/blob/master/src/ajax.js#L617 (Происходит из строк: 158, 190, 337, 617 - rhash в строке 6)

$(document).ready(function () {
    var firstLink = $("ul > li:first-child > a");
    var menuLink = $("ul > li > a");
    var firstLoadedHtml = firstLink.attr("href");

    $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast");
    firstLink.addClass("active");   

    menuLink.click(function(e) {

        e.preventDefault();
        e.stopImmediatePropagation();

        var newLoadedHtml = $(this).attr("href");

        History.pushState(null, newLoadedHtml, newLoadedHtml);

        $("#sectionContainer")
            .hide()
            .load(newLoadedHtml, function(responseText) {
                document.title = $(responseText).filter("title").text();
            })
            .fadeIn("fast");
    });

    History.Adapter.bind(window, "statechange", function() {
        menuLink.removeClass("active");
        $("a[href='" + History.getState().title + "']").addClass("active");
        $('#sectionContainer').load(document.location.href, function(responseText) {
            document.title = $(responseText).filter("title").text();
        }); 
    });
});
В конце концов, я сделал новое редактирование, которое будет работать!TESTED Даже правильная ссылка всегда будет иметь классactive!
Первая страница (Home) имеет хороший заголовок документа, все остальные страницы имеют заголовокUntitled Document Как название. Извините, вы правы, он больше не изменяет содержание истории назад / вперед. Это потому чтоdocument.location является объектом, и вам нужна строка, прежде чем это былоdocument.location + "#content" Это вернуло строку. Так вам нужноdocument.location.hrefпосмотри на мои правки.
Ой, что-то еще не правильно: при переходе назад заголовок вкладки - это относительный URL, а не заголовок, каким он должен быть! Bram Vanroy
Я мог бы что-то упустить (довольно занятый многими вещами одновременно), но это не работает. Название изменений первой и последней ссылки на ту, которая определена в разделе ", включает в себя". Также (и что более важно) кнопки "назад" больше не изменяют содержимое. У меня ощущение, что это очень простая вещь, которую я смотрю. Тестовый пример был отредактирован:bramvanroy.be/sectionLoaderTest Bram Vanroy
Это работает действительно, очень большое спасибо вам! Еще один вопрос (я все равно дам вам +100 - не беспокойтесь): меню и его переключение контролируются куки-файлами. Однако по какой-то причине «cookie» объект удаляется. Вы можете попробовать это, выполнив следующие действия: щелкните случайную ссылку, скрыть панель, перейдите на предыдущую страницу, попробуйте снова открыть панель. Проверьте консоль для деталей. Очень странно! Я не знал, как все эти трюки повлияли на куки-файлы веб-сайта ... Вы думаете, это можно исправить? Спасибо за все! Bram Vanroy
0

Вы также можете попробовать доступные плагины маршрутизации, такие какdavis.js или жеjQuery Pusher https://github.com/salvan13/jquery-pusher

Похожие вопросы