Для корректной работы history api необходимы javascript. Управление историей просмотров. Когда можно будет использовать

Before the advent of HTML5, one thing that we — as web developers — were not able to control and manipulate is the session history of a particular browsing context. Not without incurring page reloads or relying on location.hash workarounds. This is all set to change however: the HTML5 history API provides a means to perform tasks such as moving forward and backward in the session history, adding new entries into the history, and so on. In this article we"ll look at the API"s basic syntax along with a simple example to show you what"s possible.

Opera 11.50 and later support the complete API, including the pushState() and replaceState() methods, the history.state object, and the popstate event.

Basic concepts and syntax

The History API relies on a single DOM interface — the History object. There is a unique History object defined for each tab, accessed through the history attribute of the Window interface. This can be manipulated using JavaScript along with some special methods. To relate this to the actual pages in your session history, each Document object is associated with a unique instance of the tab"s History object (they all model the same underlying session history).

History objects represent each tab"s session history as a flat, comma-separated list of session history entries. Each session history entry consists of a URL or a state object (or both), and in addition can have a title, a Document object, form data, a scroll position, and other information associated with it.

The basic methods of the history object are:

  • window.history.length: Returns the number of entries in the joint session history.
  • window.history.state: Returns the current state object.
  • window.history.go(n) : Goes backwards or forwards by the specified number of steps in the joint session history. If the value you specify is zero, it will reload the current page. If it would cause the target position to be outside the available range of the session history, then nothing happens.
  • window.history.back() : Goes backwards by one step in the joint session history. If there is no previous page to go to, it does nothing.
  • window.history.forward() : Goes forwards by one step in the joint session history. If there is no next page to go to, it does nothing.
  • window.history.pushState(data, title [, url]) : Pushes the data specified in the arguments onto the session history, with the given title and URL (the URL is optional).
  • window.history.replaceState(data, title [, url]) : Updates the current entry in the session history, with the given data, title and URL (the URL is optional).

For example, to navigate backwards by two history session entries, the following code can be used:

History.go(-2)

To add history entries with history.pushState , we"d do something like this:

History.pushState({foo: "bar"}, "Title", "/baz.html")

Currently the 2nd argument of pushState and replaceState — the title of the history entry — isn"t used in Opera"s implementation, but may be one day.

To replace a history entry using history.replaceState , we would do this:

History.replaceState({foo: "bat"}, "New Title")

The (optional) state object argument for pushState and replaceState can then be accessed in history.state .

A real example

Now we"ve seen the basics, let’s look at a real example. This particular example is a web-based file explorer to help you find a URI of a particular image (view the example running live), with a simple JavaScript-based expanding/collapsing folder structure. When you select a file in the folder, the image is dynamically updated on the screen.

We are using custom data-* attributes to store each image"s caption, and then using the dataset property to access these and print them underneath their respective images:

  • crab2.png
  • Now, there is something clever going on here - when we access the main viewer.html page with a browser that supports the history API, then open a folder and click on an image, it looks like we are visiting a new page. But in fact this is not the case - every time an image is selected, it is dynamically loaded into the viewer.html page and a new history entry is written using the history API. This way, the user experience is far snappier as we aren"t loading an entire new page each time a new image is selected, and the history API usage means that we are still able to use the back button to go between different images.

    But there"s more - each page is also available at a separate URL, as a separate HTML file, so the demo will gracefully degrade in non-supporting browsers, and you can bookmark the URLs and go straight back to them. Try for example, going straight to crab.html in a browser, even one that doesn"t support the History API, or one that has JavaScript turned off completely!

    Walking through the code

    The HTML is pretty self-explanatory — two

    s sat next to one another, the left one containing the folder structure inside nested lists, and the right one providing a space to display the pictures. The dynamic functionality is all controlled via the linked JavaScript file, app.js . Apart from images and CSS, the demo relies on a single constructor function, FilePreview . We"ll only highlight relevant portions here, but the code is quite short (only 80 lines) and we encourage you to have a look at it all.

    In the bindEvents method, we set up event handlers for the popstate event on the document, as that will allow the application to know that the history has been navigated and to update the page accordingly.

    Window.addEventListener("popstate", function(e){ if (history.state){ self.loadImage(e.state.path, e.state.note); } }, false);

    Note that the event object that gets passed into the listener has a state property which corresponds to the state argument (if any) of the pushState or replaceState method call of the current history entry.

    We also listen for the click event on the

    holding our file navigation, using event delegation to know if we should open or close a folder, or load a new image into the page (which results in a history entry being added). By inspecting the className of the parent element of the link that was clicked (with the classList API) we can find out what it is, and act accordingly:

    • If it"s a folder we open or close it.
    • If it"s a photo we load the image and update the history accordingly.
    dir.addEventListener("click", function(e){ e.preventDefault(); var f = e.target; if (f.parentNode.classList.contains("folder")) { self.toggleFolders(f); } else if (f.parentNode.classList.contains("photo")){ note = f.dataset ? f.dataset.note: f.getAttribute("data-note"); self.loadImage(f.textContent, note); history.pushState({note: note, path:f.textContent}, "", f.href); } }, false);

    The actual method that changes the image and updates the caption is pretty self-explanatory:

    LoadImage: function(path, note){ img.src = path; h2.textContent = note; }

    Summary

    Put it all together and we have a simple file-browsing app that demonstrates how to use some of the additions to the History interface, namely pushState to add entries to the browsing context"s history and the popstate event to react to state changes. What"s more, each file that has been navigated to can be accessed later at its real URL.

    This highlights the real usefulness of the history API: you can create Ajaxy navigation in the style of Facebook or Twitter, without breaking the back button or the URLs to individual pages. Although bear in mind that hashbangs don"t work if you share the URL with someone who has scripting disabled.

    Перевод: Влад Мержевич

    Адресная строка браузера это, пожалуй, наиболее чокнутая часть пользовательского интерфейса в мире. Адреса сайтов есть на рекламных щитах, на поездах и даже на уличных граффити. В сочетании с кнопкой «Назад» - наиболее важной кнопкой в браузере - у вас есть мощный способ двигаться вперед и назад через огромное множество взаимосвязанных ресурсов называемых вебом.

    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 в адресной строке браузера без запуска полного обновления страницы. В неподдерживаемых браузерах - или в действительности поддерживаемых браузерах, где пользователь отключил скрипты - ссылки просто работают как обычные ссылки, переводя вас на новую страницу с полным ее обновлением.

    Это поднимает важный момент.

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

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

    Давайте обратимся к демо и посмотрим, как оно работает. Это соответствующий код для одной фотографии.

    Html">Next >

    Fer, 1972

    Ничего необычного здесь нет. Фотография это внутри

    , ссылки просто очередные элементы и все завернуто в

    Выглядит знакомо? Так и должно быть. Это тот же основной код, что у исходной страницы, используемый для отображения первой фотографии.

    Вторая половина функции swapPhoto() выполняет второй шаг нашей трехэтапной иллюзии: вставляет этот новый загруженный код в текущую страницу. Помните, что существует

    В продолжение темы:
    Windows

    Часть вторая : "Важнейшие характеристики каждого семейства процессоров Intel Core i3/i5/i7. Какие из этих чипов представляют особый интерес" Введение Сначала мы приведём...

    Новые статьи
    /
    Популярные