Новости
Вступ
History API є одним з цікавих нововведень HTML 5. Завдяки йому з'являється можливість навігації по історії одного таба браузера без перезавантаження сторінки, при цьому браузер коректно відпрацьовує функції "назад" і "вперед".
Це дає чудові можливості при використанні History API спільно з Ajax. Тепер немає необхідності використовувати традиційну конструкцію # !, можна просто замінити URL цілком. Завдяки цьому ми отримуємо наступні переваги:
- в URL тепер відображається реальний адреса сторінки, користувачі можуть спокійно копіювати посилання на сторінку з адресного рядка браузера і поширювати її;
- відмова від конструкції #! при використанні Ajax дозволяє не турбуватися про втрачені для індексації пошуковими системами посиланнях;
- посилання просто стають чистішими і красивішими.
У цій статті ми коротко розглянемо HTML5 History API і створимо простий приклад з використанням плагіна History.js для популярного Javascript фреймворку jQuery. Як приклад реалізуємо посторінкову Ajaxнавігацію на сторінці лістингу продуктів Magento.
Огляд HTML5 History API
За роботу з історією відповідає об'єкт History. Ми можемо отримати цей об'єкт для поточного таба через readonly посилання window.history.
Основні методи і властивості об'єкта History:
window.history.stateПовертає поточний об'єкт історії. За допомогою цього об'єкта можна отримати дані, які передаються методами pushState і replaceState шляхом доступу до властивостей цього об'єкта.
window.history.length
Властивість lenght показує кількість записів в історії.
window.history.go (n)
Перехід до певної позиції в історії, як аргумент передається зміщення щодо поточний позиції. Цей метод існував до появи HTML5.
window.history.back ()
Перехід до попереднього елемента в історії, ідентично викликом go (- 1).
window.history.forward ()
Перехід до наступного елементу в історії, ідентичний виклику go (1).
Методи window.history.back () і window.history.forward () також існували до HTML5.
window.history.pushState (data, title [, url])Додає новий елемент в історію. Метод приймає три параметри:
- Дані стану історії. Ці дані можна отримати потім в обробнику події popstate. Якщо додаткові дані не потрібні можна передавати null;
- Заголовок сторінки, який відобразиться у вікні браузер, так само можна передавати null;
- URL, який повинен відображатися в адресному рядку.
приклад:
history.pushState ({param: 'Value'}, '', 'myurl.html');
Якщо поточний URL був http://yoursite.com/path/to/page.html, то він буде замінений на http://yoursite.com/path/to/myurl.html, як якщо б ми перейшли звичайним способом .
URL, який передається третім параметром, може бути як відносним так і абсолютними, але використання Ajax накладає обмеження на використання тільки поточного домену.
window.history.replaceState (data, title [, url])Цей метод дуже схожий на pushState і має ті ж параметри. Відмінність полягає в тому, що даний метод не додає новий запис, а змінює поточну запис в історії.
popstate
Ця подія спрацьовує при перехід від одного елемента історії до іншого. При цьому history.pushState () і history.replaceState () не призводять до виклику цієї події. Тільки натискання кнопок вперед / назад в браузері, або виклик history.back () або аналогічної функції в Javascript.
приклад:
window.addEventListener ( 'popstate', function (e) {// код обробника події}); підтримка браузерами
History Api і jQuery
Існує цікавий плагін History.js , Який надає єдиний інтерфейс для всіх популярних браузерів для роботи з історією перегляду. Він базується на HTML5 History API і містить практично ті ж самі методи, що й об'єкт window.history. Використовуючи даний плагін, можна не турбуватися про роботу скрипта в старих браузерах. Якщо браузер не має підтримки History API, то для його емуляції буде використаний # (якір URL).
Для звернення до функцій плагіна використовується об'єкт History. Наприклад, виклик функції History.pushState (data, title, url) практично аналогічний викликом history.pushState. Детально ознайомитися з Api плагіна можна на його сайті. Однак, є 2 моменти, на які варто звернути увагу:
- Плагін використовує власну подію «statechange» замість стандартного «popstate» для визначення моменту переходу з історії;
- Методи History.pushState і History.replaceState призводять до виклику події «statechange», тоді як аналогічні методи об'єкта window.history немає.
Для демонстрації роботи плагіна додамо Ajax з динамічною зміною URL до стандартної посторінковою навігації продуктів Magento.
Завантажити плагін можна за цим посиланням https://github.com/browserstate/history.js/ . Нам буде потрібно тільки один файл jquery.history.js з папки scripts / bundled / html4 + html5 (мінімізована версія з підтримкою HTML4). Підключаємо файл плагіна і бібліотеку jQuery, якщо вона ще не підключена. У версії Magento 1.9.0.1, яку я використовував для цього прикладу, jQuery підключений за замовчуванням, тому мені досить підключити тільки файл плагіна.
Копіюємо jquery.history.js в папку / skin / frontend /// js / lib /. У моєму випадку це папка skin / frontend / rwd / default / js / lib /. У файлі розмітки page.xml поточної теми в в самий кінець блоку «head» додаємо:
<Block type = "page / html_head" name = "head" as = "head"> ... <action method = "addItem"> <type> skin_js </ type> <name> js / lib / jquery.history. js </ name> </ action> </ block>
Крім цього, нам буде потрібно окремий файл для ініціалізації плагіна і написання власного коду обробників подій. Створимо файл main.js і так само помістимо його в папку поточного скіна за адресою skin / frontend /// js /.
Підключаємо файл main.js:
<Block type = "page / html_head" name = "head" as = "head"> ... <action method = "addItem"> <type> skin_js </ type> <name> js / lib / jquery.history. js </ name> </ action> <action method = "addItem"> <type> skin_js </ type> <name> js / main.js </ name> </ action> </ block>
У файл main.js додаємо наступний код:
(Function ($) {$ (function () {var $ categoryProducts = $ ( '. Category-products'); $ categoryProducts.on ( 'click', '.pages a', function (e) {e.preventDefault ( ); History.pushState (null, document.title, $ (this) .attr ( 'href')); loadPage ($ (this) .attr ( 'href'));}); function loadPage (url) {$ categoryProducts.load (url + ".category-products> *");}});}) (jQuery);
Ми використовували саме такий синтаксис для уникнення конфліктів з бібліотекою Prototype, яку Magento використовує за замовчуванням.
(Function ($) {// код}) (jQuery);
Ми додали обробник події «click» на посилання посторінковою навігації і скасували стандартну поведінку посилань за допомогою методу e.preventDefault. Потім ми використовуємо History.pushState для додавання нового елемента в історію і в фоновому режимі завантажуємо нову сторінку за допомогою функції loadPage.
$ CategoryProducts.load (url + ".category-products> *");
Цей код завантажує сторінку за вказаною URL за допомогою Ajax і поміщає в елемент $ categoryProducts вміст блоку з класом '.category-products'.
Розглянемо докладніше виклик методу History.pushState.
History.pushState (null, document.title, $ (this) .attr ( 'href'));
Першим параметром передаємо null, так як нам не потрібно передавати додаткові параметри в об'єкт State. Другим параметром передаємо поточний заголовок документа, оскільки при переході на наступну сторінку нам не потрібно змінювати заголовок. І третім параметром передаємо новий URL - посилання, на яку натиснув користувач.
Для перевірки роботи цього прикладу потрібно зайти в будь-яку категорію з товарами, де кількість товарів досить для появи посторінковою навігації, і перейти на будь-яку іншу сторінку. Після цього URL в адресному рядку замінюється на новий, як якщо б ми перейшли з цього URL, і після невеликої паузи завантажуються товари з нової сторінки.
Наш приклад справляється зі своїм завданням, однак при натисканні кнопки «назад» в браузері нічого не відбувається. Для обробки події переходу історії нам потрібно призначити обробник на подію «statechange».
History.Adapter.bind (window, 'statechange', function (e) {var State = History.getState (); loadPage (State.url);});
Оскільки подія «statechange» спрацьовує щоразу, коли відбувається перехід з історії, нам більше не потрібно викликати функцію loadPage після History.pushState.
Після внесення необхідних правок, наш код виглядає наступним чином:
(Function ($) {$ (function () {var $ categoryProducts = $ ( '. Category-products'); $ categoryProducts.on ( 'click', '.pages a', function (e) {e.preventDefault ( ); History.pushState (null, document.title, $ (this) .attr ( 'href'));}); function loadPage (url) {$ categoryProducts.load (url + ".category-products> *") ;} History.Adapter.bind (window, 'statechange', function (e) {var State = History.getState (); loadPage (State.url);});});}) (jQuery);
Тепер при натисканні в браузері кнопок вперед / назад спрацьовує подія «statechange» і вміст сторінки коректно оновлюється. Для наочного відображення процесу завантаження трохи змінимо функцію loadPage, додавши зміна прозорості блоку з продуктами на час завантаження контенту.
function loadPage (url) {$ categoryProducts.css ({opacity: 0.5}); $ CategoryProducts.load (url + ".category-products> *", function () {$ categoryProducts.css ({opacity: 1});}); }
На цьому наш простий приклад завершено. Як бачите, використання History API не представляє особливих складнощів. Ви легко можете використовувати красиві URL в Ваших Ajax-додатках, не боячись проблем з пошуковими системами, а використаний в прикладі плагін дозволить уникнути проблем в старих браузерах.
Дякую за увагу!