Новости

Управління історією для користі і розваги

  1. чому
  2. як
  3. Професор Маркап говорить

оригінал: http://diveintohtml5.info/history.html

Переклад: Влад Мержевіч

Адресний рядок браузера це, мабуть, найбільш чокнутая частина призначеного для користувача інтерфейсу в світі. Адреси сайтів є на рекламних щитах, на поїздах і навіть на вуличних графіті. У поєднанні з кнопкою «Назад» - найбільш важливою кнопкою в браузері - у вас є потужний спосіб рухатися вперед і назад через безліч взаємопов'язаних ресурсів званих Інтернетом.

API історії HTML5 є стандартизований спосіб маніпулювати історією браузера через скрипт. Частина цього API - навігація по історії - була доступна в попередніх версіях HTML. Нові частини в HTML5 включають спосіб додавання записів в історію браузера, щоб помітно змінити URL в адресному рядку браузера (без перемикання поновлення сторінки) і події, які запускаються, коли ці записи видаляються з стека користувача натисканням кнопки браузера «Назад». Це означає, що URL в адресному рядку браузера може продовжувати виконувати свою роботу як унікальний ідентифікатор для поточного ресурсу, навіть в додатках навантаженими скриптами, які не завжди виконують повне оновлення сторінки.

чому

Чому б вам вручну не зраджувати адресний рядок браузера? Зрештою, проста посилання може перейти на новий URL, цей спосіб працював протягом 20 років. І він буде продовжувати працювати таким чином. Цей API не намагається підірвати веб. Якраз навпаки. В останні роки веб-розробники знайшли нові та захоплюючі способи підриву інтернету без будь-якої допомоги з боку нових стандартів. API історії HTML5 насправді призначений для того, щоб адреси продовжували бути корисними в веб-додатках навантаженими скриптами.

Повертаючись до початкових принципів, що тепер робить URL? Він визначає унікальний ресурс. Ви можете вказати посилання безпосередньо, додати її в закладки, пошукові системи її індексують, ви можете скопіювати і вставити її, відправити поштою комусь ще, хто може натиснути посилання і в кінцевому підсумку побачить той же ресурс, що і ви спочатку. Всі ці прекрасні якості URL зберігаються.

Тому ми хочемо, щоб унікальні ресурси мали унікальний URL. Але в той же час браузери завжди мали фундаментальне обмеження: якщо ви зміните URL, навіть через скрипт, це включить запит до віддаленого веб-сервера і призведе до оновлення сторінки. Це вимагає часу і ресурсів, що, здається, особливо марнотратно, коли ви переміщується на сторінку, яка в значній мірі схожа на поточну. Все на новій сторінці буде завантажено, включаючи ті частини, які точно такі ж, як на поточній сторінці. Немає способу сказати браузеру змінити URL і завантажити тільки половину сторінки.

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

Скажімо, у вас є дві сторінки, сторінка А та сторінка Б. Дві сторінки на 90% ідентичні і тільки 10% вмісту сторінок різниться. Користувач переходить на сторінку А, потім намагається перейти на сторінку Б. Але замість запуску повного оновлення сторінки, ви перериваєте цю навігацію і робите такі кроки вручну:

  1. Завантажуєте 10% з сторінки Б, які відрізняються від сторінки А (можливо за допомогою XMLHttpRequest). Це зажадає деяких серверних зміни в вашому веб-додатку. Вам потрібно буде написати код, який повертає тільки 10% від сторінки Б, що відрізняються від сторінки А. Це може бути прихований URL або параметр запиту, невидимий кінцевому користувачеві.
  2. Обмінюєте змінене зміст (з використанням innerHtml або інших методів DOM). Вам також може знадобитися скинути будь-який обробник подій для елемента всередині обмінного змісту.
  3. Оновлюєте рядок браузера з адресою сторінки Б, використовуючи особливий метод з API історії HTML5, що я вам покажу в даний момент.

В кінці цієї ілюзії (якщо виконана правильно) браузер отримує DOM ідентичний сторінці Б, як якщо б ви перейшли сторінку Б безпосередньо. Рядок браузера буде містити URL, який ідентичний сторінці Б, як якщо б ви перейшли на сторінку Б безпосередньо. Але в дійсності ви не переходили на сторінку Б і не робили повного оновлення сторінки. Це ілюзія. Але оскільки «компілювати» сторінка виглядає так само, як сторінка Б і має той же URL, що у сторінки Б, користувач ні за що не помітить різниці (і не оцінить вашу важку працю по мікрокерування цього досвіду).

як

API історії HTML5 це просто купка методів об'єкта window.history плюс одна подія в об'єкті window. Ви можете використовувати їх, щоб визначити підтримку для API історії. Підтримка в даний час обмежується самими останніми версіями деяких браузерів, поміщаючи ці методи прямо в табір «прогресивного поліпшення».

Підтримка історії IE Firefox Safari Chrome Opera iPhone Android 9.0 4.0+ 5.0+ 8.0+ 11.10 4.2.1+ -

Dive into dogs це простий, але не тривіальний приклад використання API історії HTML5. Він демонструє типовий шаблон: велика стаття з пов'язаної вбудованої фотогалереєю. У підтримуваних браузерах натискання на посилання Next і Previous в фотогалереї буде оновлювати фото в тому ж місці і оновлювати URL в адресному рядку браузера без запуску повного оновлення сторінки. У підтримуються браузерах - або в дійсності підтримуваних браузерах, де користувач відключив скрипти - посилання просто працюють як звичайні посилання, переводячи вас на нову сторінку з повним її оновленням.

Це піднімає важливе момент.

Професор Маркап говорить

Якщо ваше веб-додаток зазнає невдачі в браузерах з відключеними скриптами, собака Якоба Нільсена прийде до вас додому і насрет на ваш килим.

Давайте звернемося до демо і подивимося, як воно працює. Це відповідний код для однієї фотографії.

<Aside id = "gallery"> <p class = "photonav"> <a id="photonext" href="http://htmlbook.ru/casey.html"> Next & gt; </a> <a id = "photoprev" href = "http://htmlbook.ru/adagio.html"> & lt; Previous </a> </ p> <figure id = "photo"> <img id = "photoimg" src = "http://htmlbook.ru/gallery/1972-fer-500.jpg" alt = "Fer" width = "500" height = "375"> <figcaption> Fer, 1972 </ figcaption> </ figure> </ aside>

Нічого незвичайного тут немає. Фотографія це <img> всередині <figure>, посилання просто чергові елементи <a> і все загорнуте в <aside>. Важливо, що це всього лише звичайні посилання, які дійсно працюють. Весь код слід після скрипта перевірки. Якщо користувач використовує непідтримуваний браузер, наш химерний код з API історії ніколи не буде виконано. І звичайно в цілому завжди є деякі користувачі з відключеними скриптами.

Основна функція програми отримати кожну з цих посилань і передати її функції addClicker (), яка робить фактичну роботу зі створення призначеного для користувача обробника click.

function setupHistoryClicks () {addClicker (document.getElementById ( "photonext")); addClicker (document.getElementById ( "photoprev")); }

Це функція addClicker (). Вона бере елемент <a> і додає обробник click. З цим обробником виходить цікавіше.

function addClicker (link) {link.addEventListener ( "click", function (e) {swapPhoto (link.href); history.pushState (null, null, link.href); e.preventDefault ();}, false); }

Функція swapPhoto () виконує перші два кроки з трьох нашої триетапної ілюзії. У першій половині функції swapPhoto () береться частина адреси посилання - casey.html, adagio.html і ін. - і будується URL в прихованій сторінці, яка містить тільки код, необхідний для нових зображень.

function swapPhoto (href) {var req = new XMLHttpRequest (); req.open ( "GET", "http://diveintohtml5.info/examples/history/gallery/" + href.split ( "/"). pop (), false); req.send (null);

Цей зразок розмітки повертає http://diveintohtml5.info/examples/history/gallery/casey.html (Ви можете перевірити це в браузері, вставивши URL безпосередньо).

<P class = "photonav"> <a id="photonext" href="http://htmlbook.ru/brandy.html"> Next & gt; </a> <a id = "photoprev" href = "http: //htmlbook.ru/fer.html">&lt; Previous </a> </ p> <figure id = "photo"> <img id = "photoimg" src = "http://htmlbook.ru/gallery/1984-casey-500.jpg" alt = "Casey" width = "500" height = "375"> <figcaption> Casey, 1984 </ figcaption> </ figure>

Виглядає знайомо? Так і має бути. Це той самий основний код, що у вихідній сторінки, використовуваний для відображення першої фотографії.

Друга половина функції swapPhoto () виконує другий крок нашої триетапної ілюзії: вставляє цей новий завантажений код в поточну сторінку. Пам'ятайте, що існує <aside> обертається все зображення, фотографію і підпис. Вставка коду нової фотографії це жарт, досить встановити властивість innerHtml для <aside> в властивість responseText, яке повертається від XMLHttpRequest.

if (req.status == 200) {document.getElementById ( "gallery"). innerHTML = req.responseText; setupHistoryClicks (); return true; } Return false; }

Також зверніть увагу на виклик setupHistoryClicks (). Це необхідно, щоб скинути призначений для користувача обробник подій click для нових вставлених посилань. Установка innerHtml стирає будь-які сліди старих посилань і їх обробників подій.

Тепер давайте повернемося до функції addClicker (). Після успішної зміни фотографії є ​​ще один крок в нашій триетапної ілюзії: встановити URL в адресному рядку браузера без перезавантаження сторінки.

history.pushState (null, null, link.href);

Функція history.pushState () містить три параметри:

  1. state може бути будь-якою структурою даних JSON. Він передається назад оброблювачу подій popstate, про який ви дізнаєтеся трохи пізніше. Нам не потрібно стежити за state в цій демонстрації, так що я залишив його як null.
  2. title може бути будь-який рядком. Цей параметр в даний час не використовується основними браузерами. Якщо ви хочете встановити заголовок сторінки, ви повинні зберегти його в аргументі state і встановити вручну в popstate.
  3. url може бути, ну, будь-яким URL. Це URL, який повинен відображатися в адресному рядку браузера.

Виклик history.pushState негайно змінить URL в адресному рядку браузера. Так це кінець ілюзії? Ну не зовсім. Нам ще потрібно сказати про те, що відбувається, коли користувач натискає важливу кнопку «Назад».

Зазвичай, коли користувач переходить на нову сторінку (з повним оновленням сторінки), браузер поміщає новий URL в стек історії, завантажує і отрісовиваєт нову сторінку. Коли користувач натискає кнопку «Назад», браузер зрушує одну сторінку в стеці історії і перемальовує попередню сторінку. Але що відбувається тепер, коли ви зробили коротке замикання цієї навігації, щоб уникнути повного оновлення сторінки? Отже, ви підроблено «рушили вперед» на новий URL, так що тепер необхідно також підроблене «рушити назад» до попереднього URL. І ключ до підробленим «рушити назад» у події popstate.

window.addEventListener ( "popstate", function (e) {swapPhoto (location.pathname);}, false)

Після того як ви використовували функцію history.pushState () для зсуву підробленого URL в стеці історії браузера, коли користувач натискає кнопку «Назад», в браузері спрацьовує подія popstate на об'єкті window. Це ваш шанс завершити ілюзію раз і назавжди. Тому що мало зробити зникнення чогось, ви також повинні повернути його.

У цій демонстрації «повернути його» так само просто, як зміна вихідної фотографії, яку ми робимо за допомогою виклику swapPhoto () в поточній локації. На той час popstate буде викликаний, URL відображається в адресному рядку браузера як змінений на попередній URL. Крім того, глобальне властивість location вже був оновлено з попереднім URL.

Щоб допомогти вам уявити це, давайте пройдемо по кроках через всю ілюзію від початку до кінця:

  • Користувач завантажує http://diveintohtml5.info/examples/history/fer.html , Дивиться історію і фотографію Фер.
  • Користувач клацає по посиланню Next, у елемента <a> атрибут href встановлений як http://diveintohtml5.info/examples/history/casey.html .
  • Замість переходу на http://diveintohtml5.info/examples/history/casey.html з повною перезавантаженням сторінки, призначений для користувача обробник click на елементі <a> перехоплює клацання і виконує власний код.
  • Наш власний обробник click викликає функцію swapPhoto (), яка створює об'єкт XMLHttpRequest для синхронної завантаження фрагмента HTML за адресою http://diveintohtml5.info/examples/history/ gallery /casey.html .
  • Функція swapPhoto () встановлює властивість innerHTML обгортці фотогалереї (елемент <aside>), тим самим замінивши фотографію Фер на фотографію Кейсі.
  • Нарешті, наш обробник click викликає функцію history.pushState (), щоб вручну змінити URL в адресному рядку браузера на http://diveintohtml5.info/examples/history/casey.html .
  • Користувач натискає кнопку «Назад» браузера.
  • Браузер зауважує, що URL вручну поміщається в стек історії (по функції history.pushState ()). Замість того, щоб перейти на попередній URL і перемалювати всю сторінку, браузер просто оновить адресний рядок на попередній URL ( http://diveintohtml5.info/examples/history/fer.html ) І запустить подія popstate.
  • Наш користувальницький обробник popstate знову викличе функцію swapPhoto (), на цей раз з попереднім URL, що зараз вже видно в адресному рядку браузера.
  • Знову використовуючи XMLHttpRequest, функція swapPhoto () завантажує фрагмент HTML розташований в http://diveintohtml5.info/examples/history/ gallery /fer.html і встановлює властивість innerHtml для елемента <aside>, тим самим замінюючи фотографію Кейсі на фотографію Фер.

Ілюзія завершена. Всі видимі докази (зміст сторінки і URL в адресному рядку) переконують користувача, що у нього був перехід вперед і назад на сторінку. Але повного оновлення сторінки не відбувається - все це було ретельно виконаної ілюзією.

Що ще почитати

Повертаючись до початкових принципів, що тепер робить URL?
Ви уважно стежите?
Так це кінець ілюзії?
Але що відбувається тепер, коли ви зробили коротке замикання цієї навігації, щоб уникнути повного оновлення сторінки?

Уважаемые партнеры, если Вас заинтересовала наша продукция, мы готовы с Вами сотрудничать. Вам необходимо заполнить эту форму и отправить нам. Наши менеджеры в оперативном режиме обработают Вашу заявку, свяжутся с Вами и ответят на все интересующее Вас вопросы.

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: