Гарний підручник для використання API історії HTML5 (Pushstate?) [Закрито]


168

Я розглядаю використання API історії HTML5 для вирішення проблем глибокого зв’язку із вмістом, завантаженим AJAX, але я намагаюся вийти з місця. Хтось знає про якісь хороші ресурси?

Я хочу використати це, оскільки це здається чудовим способом дозволити можливість передачі посилань, можливо, не ввімкнено JS. Багато рішень не вдається, коли хтось із JS надсилає посилання комусь без.

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

http://html5demos.com/history

Відповіді:


181

Для чудового підручника сторінка Мережі розробників Mozilla на цій функціональності - це все, що вам знадобиться: https://developer.mozilla.org/uk/DOM/Manipulating_the_browser_history

На жаль, API історії HTML5 реалізується по-різному у всіх браузерах HTML5 (що робить його непослідовним і помилковим) і не має резервного доступу для браузерів HTML4. На щастя, History.js забезпечує перехресну сумісність для браузерів HTML5 (забезпечуючи роботу всіх браузерів HTML5 так, як очікувалося) та необов'язково забезпечує хеш-запас для браузерів HTML4 (включаючи підтримувану підтримку даних, заголовків, функцій pushState та substituState).

Детальніше про 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
Безсоромний самовідвід. Відмінний пост і плагін, хоча. :)
Purag

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!
adriendenat

13
В ідеалі ваш сервер / додаток повинен відповідати маршруту належним чином, не потребуючи цього переписувати.
sholsinger

Погоджено, за винятком багатьох сучасних фреймворків JavaScript, таких як Backbone.js, Spine, Ember тощо. Це все по суті програми на одній сторінці. Можна було б розробити рішення щодо подачі шаблону запису резервного запису для SEO, ect, але тим часом це було б необхідно.
Мавіс Ледфорд

* правильно. Я пишу про це більш детально тут: readystate4.com/2012/05/17 / ...
Mauvis Ледфорд

6

Специфікація історії HTML5 химерна.

history.pushState() не відправляє a 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 API, щоб надіслати новий стан І відправити поп-події.

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 API може працювати в поєднанні з modrewrite, так що посилання завжди обробляються в першу чергу сервером, не потребуючи перенаправлення з шару JS.
Легкий фуз

Ви на правильному шляху з modrewrite. Рішення управління API історії та обробки, коли у користувача немає JS, - це справді дві окремі речі. Якщо у вас немає JS, ви маєте працювати з користувачем за допомогою стандартних hrefs та відповідей сервера. API історії можна створити як «приємне мати», якщо браузер користувача підтримує його.
Натан Тоттен

І зразки Express, і State, що постачаються з jQuery Address 1.3, працюють досить добре, коли JavaScript відключений. У другому використовується PHP з mod_rewrite.
Ростислав

Точно мій такт. Я маю намір створити сайт без JS, додати елементи AJAX, а потім використовувати історію, щоб переписати URL, зберігаючи глибоке посилання. Теоретично це повинен бути кращий метод, ніж будь-який, який я бачив, оскільки сайт не залежатиме від AJAX на будь-якому етапі
Mild Fuzz

1
-1, оскільки адреса jQuery не є прямим портом API стану HTML5 - не підтримує дані чи заголовки та замінюєState.
балуптон

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-адреси.
скругман

1
в цьому полягає API історії HTML5 - він нічого не порушує
balupton

2
@MildFuzz Комп'ютер, здається, виходить з ладу без джерела живлення! Я думаю, у вас помилка ID-10-T ...
Ерік Ходонський

1
Як не дивно, це ти , що є misundestood
Mild Fuzz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.