Хороший учебник по использованию HTML5 History API (Pushstate?) [Закрыто]


168

Я пытаюсь использовать API истории HTML5 для решения проблем с глубокими ссылками с загруженным контентом AJAX, но я изо всех сил пытаюсь уйти с земли. Кто-нибудь знает какие-нибудь хорошие ресурсы?

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

Мои первоначальные исследования, похоже, указывают на History API в JS и метод pushState.

http://html5demos.com/history

Ответы:


181

Для отличного учебника на странице Mozilla Developer Network, посвященной этой функциональности, есть все, что вам нужно: https://developer.mozilla.org/en/DOM/Manipulation_the_browser_history

К сожалению, API истории HTML5 реализован по-разному во всех браузерах HTML5 (что делает его непоследовательным и ошибочным) и не имеет отступления для браузеров HTML4. К счастью, History.js обеспечивает перекрестную совместимость для браузеров HTML5 (гарантируя, что все браузеры HTML5 работают должным образом) и, при необходимости, обеспечивает откат хеш-функций для браузеров HTML4 (включая поддерживаемую поддержку данных, заголовков, функциональных возможностей pushState и replaceState).

Вы можете прочитать больше о History.js здесь: https://github.com/browserstate/history.js

Чтобы узнать о статье Hashbangs VS Hashes VS HTML5 History API, см. Здесь: https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling.


25
Бесстыдная самостоятельная вилка. Отличный пост и плагин, хотя. :)
Пураг

33

Я получил много пользы от «Погружения в HTML 5». Объяснение и демонстрация проще и точнее. Глава по истории - http://diveintohtml5.info/history.html и демонстрационная история - http://diveintohtml5.info/examples/history/fer.html


1
Отличный учебник действительно. Тем временем URL-адрес стал diveintohtml5.info ; возможно, захотите обновить ответ.
Дан Даскалеску

28

Имейте в виду, что при использовании pushstate HTML5 пользователь копирует или добавляет закладку в глубокую ссылку и снова посещает ее, тогда это будет прямым попаданием на сервер, которое будет 404, поэтому вам нужно быть готовым к нему, и даже библиотека pushstate js не поможет ты. Самое простое решение - добавить правило перезаписи на сервер Nginx или Apache следующим образом:

Apache (в вашем vhost, если вы его используете):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
 </IfModule>

Nginx

rewrite ^(.+)$ /index.html last;

Это реальный ответ. Этого нигде нет в вики / руководствах Balupton's History.js и т. Д. На самом деле History.js не использует хеш, поэтому вам нужно использовать перенаправление .htaccess!
Адриенденат

13
В идеале ваш сервер / приложение должно реагировать на маршрут соответствующим образом без необходимости перезаписи.
Шолзингер

Согласен, за исключением многих современных JavaScript-фреймворков, таких как Backbone.js, Spine, Ember и т. Д. Все они по сути являются «одностраничными» JavaScript-приложениями. Можно было бы найти решение, обслуживающее шаблон обратной записи для SEO, но в то же время это было бы необходимо.
Mauvis Ledford

*право. Я пишу об этом более подробно здесь: readystate4.com/2012/05/17/…
Mauvis Ledford

6

Спецификация истории HTML5 является странной.

history.pushState()не отправляет popstateсобытие и не загружает новую страницу самостоятельно. Это должно было только подтолкнуть государство в историю. Это функция отмены для одностраничных приложений. Вы должны вручную отправить popstateсобытие или использовать history.go()для перехода в новое состояние. Идея заключается в том, что маршрутизатор может прослушивать popstateсобытия и выполнять навигацию за вас.

Некоторые вещи, на которые стоит обратить внимание:

  • history.pushState()и history.replaceState()не отправлять popstateсобытия.
  • history.back(), history.forward()и кнопки браузера «назад» и «вперед» отправляют popstateсобытия.
  • history.go()и history.go(0)сделать полную перезагрузку страницы и не отправлять popstateсобытия.
  • history.go(-1)(1 страница назад) и history.go(1)(1 страница вперед) popstateсобытия отправки .

Вы можете использовать API истории, как этот, чтобы выдвинуть новое состояние И отправить событие popstate.

history.pushState({message:'New State!'}, 'New Title', '/link'); window.dispatchEvent(new PopStateEvent('popstate', { bubbles: false, cancelable: false, state: history.state }));

Тогда слушайте popstateсобытия с роутером.


1
Это только у меня, или, new PopStateEvent(...)кажется, не работает в IE11? Есть ли обходной путь, о котором кто-нибудь знает?
Дэвид Алан Хьелле

Похоже, IE 11 нужно что-то вроде: var pop_state_event = document.createEvent('Event'); pop_state_event.initEvent('popstate', true, true); window.dispatchEvent(pop_state_event);
Дэвид Алан Хьелле

4

Вы можете попробовать Davis.js , он дает вам маршрутизацию в вашем JavaScript, используя pushState, когда он доступен, и без JavaScript, он позволяет коду на стороне сервера обрабатывать запросы.



2

Возможно, вы захотите взглянуть на этот плагин jQuery. У них есть много примеров на своем сайте. http://www.asual.com/jquery/address/


Снова, это решение, кажется, терпит неудачу, когда JS выключен. Я думаю, что API истории может работать совместно с modrewrite, так что ссылки всегда обрабатываются сервером в первую очередь, без необходимости перенаправления со слоя JS.
Мягкий пух

Вы находитесь на правильном пути с Modrewrite. Решение об управлении API истории и обработке, когда у пользователя нет JS, на самом деле две разные вещи. Если у вас нет JS, вы должны обрабатывать пользователя с помощью стандартных ссылок и ответов сервера. API истории можно построить как «приятно иметь», если браузер пользователя поддерживает его.
Натан Тоттен

Образцы Express и State, которые поставляются с jQuery Address 1.3, работают достаточно хорошо, когда JavaScript отключен. Второй использует PHP с mod_rewrite.
Ростислав

Именно мой такт. Я намерен создать сайт без JS, добавить элементы AJAX, а затем использовать историю, чтобы переписать URL, сохранив глубокие ссылки. Теоретически, это должен быть лучший метод, чем любой, который я видел, так как сайт не будет зависеть от AJAX, на любом этапе
Mild Fuzz

1
-1, поскольку jQuery Address не является прямым портом API состояния HTML5 - не поддерживает данные или заголовки и replaceState.
Балуптон

2

Я написал очень простую абстракцию маршрутизатора поверх History.js, которая называется StateRouter.js . Он находится на очень ранних стадиях разработки, но я использую его в качестве решения для маршрутизации в одностраничном приложении, которое я пишу. Как и вы, я обнаружил, что History.js очень трудно понять, тем более что я довольно плохо знаком с JavaScript, пока не понял, что вам действительно нужна (или должна иметь) абстракция маршрутизации поверх нее, поскольку она решает низкоуровневый проблема.

Этот простой пример кода должен продемонстрировать, как он используется:

var router = new staterouter.Router();
// Configure routes
router
  .route('/', getHome)
  .route('/persons', getPersons)
  .route('/persons/:id', getPerson);
// Perform routing of the current state
router.perform();

Вот небольшая скрипка, которую я придумал, чтобы продемонстрировать ее использование.


1
Эта скрипка не работает для меня в Chrome на Mac. Выдает ошибку. (Uncaught ReferenceError: staterouter не определен)
DrewT

@DrewT Спасибо, скрипка была сломана из-за изменений на github.com, но я обошел ее.
aknuds1

Да, работаю сейчас, спасибо за быстрый ответ.
DrewT

1

если jQuery доступен, вы можете использовать jQuery BBQ


Похоже, что это не с JS выключен.
Мягкий пух

это, вероятно, правда - не смотрел на это. Я думаю, что у вас возникнет такая проблема со всеми подходами, основанными на js-библиотеках. Они основаны на манипулировании хеш-частью URL.
sprugman

1
в этом смысл API истории HTML5 - он ничего не нарушает
balupton

2
@MildFuzz Компьютер, кажется, выходит из строя без источника питания! Я думаю, что у вас ошибка ID-10-T ...
Эрик Ходонски

1
По иронии судьбы, это вы неправильно поняли
Mild Fuzz
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.