Управление историей просмотров. Введение в HTML5 History API

Управление историей просмотров. Введение в HTML5 History API

24.05.2019

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.

    Здравствуйте, уважаемые читатели a! Сегодняшняя статья будет посвящена работе с HTML5 History API . В прошлых версиях HTML у нас был ограниченный контроль над историей браузера. Мы могли перемещаться по истории вперед и назад с помощью доступных методов. Теперь, благодаря HTML5 History API, у нас есть больше возможностей использования истории браузера пользователя: можно «гулять» по истории, добавлять свои элементы в историю и обновлять текущую запись в истории.

    Что это?

    HTML5 History API представляет собой стандартизированный способ манипулировать историей браузера с помощью . Часть этого API — навигация по истории, была доступна в предыдущих версиях HTML. В HTML5 включили возможность добавлять записи в историю браузера, чтобы визуально изменить URL в адресной строке браузера (без обновления страницы) и заменять текущую запись в истории браузера. Это означает, что URL в адресной строке браузера так и остается уникальным идентификатором для текущего ресурса, даже в приложениях с большим количеством скриптов, которые зачастую не выполняют полного обновления страницы.

    Поддержка браузеров

    На текущий момент данный API поддерживается множеством браузеров. Более подробно Вы можете узнать об этом .

    Чтобы программно определить, поддерживается ли API, используем:

    Если браузер не поддерживает API или Вы ищете кроссбраузерное решение, то можно использовать плагин history.js . Построен на основе HTML5 History API и использует те же самые методы, в то же время можно не беспокоиться о работоспособности в старых браузерах.

    Методы и свойства API

    Простой пример использования

    Давайте рассмотрим на примере работу с методом pushState . Допустим имеются 3 страницы почти с одинаковым содержанием. Разметка выглядит следующим образом:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14



    Главная
    О нас
    Контакты


    Нажмите на ссылки выше, чтобы использовать метод pushState .

    Главная!
    Здесь какой-то текст главной страницы.


    Вот как мы будем обрабатывать клики в меню:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    $("document" ) .ready (function () {
    $(".historyAPI" ) .on ("click" , function (e) {
    // отменяем стандартное действие при клике
    e.preventDefault () ;
    // Получаем адрес страницы
    var href = $(this ) .attr ("href" ) ;
    // Передаем адрес страницы в функцию
    getContent(href, true ) ;
    } ) ;
    } ) ;

    // Добавляем обработчик события popstate,
    // происходящего при нажатии на кнопку назад/вперед в браузере
    window.addEventListener ("popstate" , function (e) {
    // Передаем текущий URL
    getContent(location.pathname , false ) ;
    } ) ;

    // Функция загрузки контента
    function getContent(url, addEntry) {
    $.get (url) .done (function (data) {
    // Обновление только текстового содержимого в сером блоке
    $("#contentHolder" ) .html ($(data) .find ("#contentHolder" ) .html () ) ;
    // Если был выполнен клик в меню - добавляем запись в стек истории сеанса
    // Если была нажата кнопка назад/вперед, добавлять записи в историю не надо
    if (addEntry == true ) {
    // Добавляем запись в историю, используя pushState
    history.pushState (null , null , url) ;
    }
    } ) ;
    }

    Вы можете перейти на демонстрационную страницу, чтобы наглядно посмотреть как все происходить при использовании метода pushState . Или скачать исходники и поэкспериментировать.

    Until recently, we developers couldn’t to do much with the state and history of the browser. We could check the number of items in the history and push users forwards and backwards, but this provides little benefit to the user. With the rise of more dynamic web pages, we need more control. Thankfully, HTML5 gives us that control by extending the JavaScript History API.

    What’s the point?

    It goes without saying that URLs are important. They’re the method of accessing the vast collections of information and resources on the web, and more recently, they’ve begun representing the intended state of a web application. You can copy these URLs and share them with your friends or use them to create links from any HTML document. They’re the veins of the web, and they need to be looked after.

    Previously, the JavaScript History API offered some very simple functionality:

    // Check the length of the history stack console.log(history.length); // Send the user agent forward console.log(history.forward()); // Send the user agent back console.log(history.back()); // Send the user agent back (negative) or forward (positive) // by a given number of items console.log(history.go(-3));

    With dynamic Ajax web applications, where the browser updates the page in parts instead of changing location entirely, it’s difficult to give the user a URL to bookmark or share the current application state. Fragment identifiers , like those used on this article’s headings via the id attribute, provide some state information, but they’re entirely dependent on client-side scripts.

    Save this file and open it in your favourite editor. It must be accessed via HTTP, so that means you need either a local server (e.g. http://localhost/) or an online web server you can upload to. Viewing the file directly using your browser’s Open File function will not work , since it uses the file:// protocol and not HTTP. Also be sure to update the href attributes on each of the navigation links to ensure the correct directory structure is used. Personally, I’m viewing the demo locally at http://localhost/history .

    We’ll be working exclusively within the element at the end of the . The code includes some simple styles and dynamically changes the content as you click the links. In reality, this could be loaded from your server via XMLHttpRequest , but for the purposes of this demonstration I’ve bundled it up into a self-contained file. The important part is that we have a quick-and-dirty dynamic page to work with, so let the fun begin!

    At the moment there, is no bookmarkable URL for the different states of this page. If you click around the navigation items, then click Back in your browser, you won’t be taken back to the previous state and may even be taken away from the page to whatever you viewed before (depending on your browser). It would be nice if you could share “Socks” with your friends, right? We can do that via history.pushState() .

    The history.pushState() method takes three parameters:

    Data Some structured data, such as settings or content, assigned to the history item. title The name of the item in the history drop-down shown by the browser’s back and forward buttons. (Note: this is not currently supported by any major browsers.) url (optional) The URL to this state that should be displayed in the address bar.

    With these parameters, you can define the state of the page, give that state a name, and even provide a bookmarkable address, as if the page had reloaded entirely. Let’s dive right in and add this to the clickHandler function, right above the return statement:

    Function clickHandler(e) { /* Snip... */ // Add an item to the history log history.pushState(data, event.target.textContent, event.target.href); return event.preventDefault(); }

    The single line of code we added informs the history object that:

    • we want to add an item to the log,
    • it should remember the data that we’ve already loaded,
    • it should assign a name to this state based on the text of the link we clicked (even though this isn’t used - it’s good to get into the habit of recording a name for the state), and
    • it should update the address bar with the href attribute of that link.

    Reload the page in your browser and click a few of the links, keeping an eye on the address bar. Notice how it changes on each click, despite the fact that you aren’t actually navigating away from this page. If you also have a look at your history log, you’ll see a long list of page titles (in this case ”Kittens!” over and over). Provided your server is set up to serve the correct page upon access, the user could copy that URL and paste it into a new browser window to jump straight to that kitten.

    At the moment, clicking the back button will pop you through the history items, but the page won’t react to these changes. That’s because so far, we’ve only created the history records. How can we allow active users to return to a previous state? We listen to the popstate event.

    Historical Events in Navigation

    The user agent fires a popstate event when the user navigates through their history, whether backwards or forwards, provided it isn’t taking the user away from the current page. That is, all those pushState s we called will keep the user on the current page, so the popstate event will fire for each history item they pop through.

    Before the closing tag, add a new listener for the popstate event:

    // Revert to a previously saved state window.addEventListener("popstate", function(event) { console.log("popstate fired!"); updateContent(event.state); });

    We attach the event listener to the window , which is responsible for firing the event, and pass this event into our handler. We log a message (so we can see when this event is firing), and then we update the content using the state we saved previously. The state is attached to the event object via the state property.

    Open up the page fresh in your browser, click around like before, and then click back. As before, the URL in the address bar changes as you cycle through states, but now the content is also restored back to what it should be. Click forward, and the content is likewise correctly restored.

    If you look at the developer console in Chrome when you load the page for the first time, you’ll see the popstate event fired immediately, before you’ve even clicked a link. This is because Chrome considers the initial page load to be a change in state, and so it fires the event. In this instance, the state property is null , but thankfully the updateContent function deals with this. Keep this in mind when developing as it could catch you out, especially if other browsers assume this behavior.

    Rewriting history

    Unfortunately, as fantastic as HTML5 is, it doesn’t allow us actual time travel. If it did, I would be going back to my childhood and telling a younger me, “Yes, you should have a slice of cake”. Take that as you will.

    The History API does, however, allow us to make amends to our history log items. For example, we could update the current state in response to fresh user input in a form. We can do this with history.replaceState .

    replaceState works just as pushState does, with the exact same parameters, except that it updates the current entry instead of adding a new one. I can think of one situation in our demo where this could be used: the initial page load. If you click back for long enough, you’ll find that going back to the original URL doesn’t provide you the original content. Let’s fix that by adding the following to the bottom of our script:

    // Store the initial content so we can revisit it later history.replaceState({ content: contentEl.textContent, photo: photoEl.src }, document.title, document.location.href);

    As this runs when the page loads, it saves the initial page state. We can later load this state when the user browses back to this point via the event listener we set up previously. You can try it out by loading up the page, clicking a few links, and then hitting back until you return to the original URL. The initial content has returned!

    Demo

    I’ve set up a demo of our completed code. I’ve also added a little back-end magic to make our history.pushState URLs work like a real site. Remember that the URLs you push should be live URLs that the user can bookmark and share as real entry points to your site.

    Browser support

    Up-to-date copies of Chrome (5+), Safari (5.0+), Firefox (4.0+), and Opera (11.50+) have support for the new History API. Even some mobile browsers work just fine, like Mobile Safari on iOS 4+. Unfortunately, IE 9 and below lack support, but it when it arrives.

    Safari 5.0 sometimes exhibits one oddity: navigating between states causes the loading spinner to appear and stay even when the state has been loaded. This stops when you navigate away using a link or action that does not involve a state saved by the History API.

    Polyfill

    A polyfill does exist for the History API. The aptly named History.js uses HTML4’s hashchange event with document fragment identifiers to mimic the history API in older browsers. If one of the hash URLs is used by a modern browser, it uses replaceState to quietly correct the URL.

    It sounds like magic, but make sure you’re aware of the consequences of using fragment identifiers, as mentioned previously in this article. As such, the author of History.js has put together a guide titled Intelligent State Handling .

    Closing thoughts

    URLs go beyond just the browsing session of a user. They’re historically important markers for resources that could very well remain in use for many years to come. Before you embark on developing your site’s JavaScript, you should give thought to the design of your URLs . Make them meaningful and organised. Make sure you can directly access them without JavaScript. Only then should you add your JavaScript to enhance the browsing experience.

    • Category
    26 Responses on the article “Pushing and Popping with the History API”

    I literally *just* discovered this and worked on this for a client two weeks ago. I even contemplated writing a blog about it because of how cool I found this. This really can be a game changer.

    I’m surprised you did not cover the history.state feature? I believe this is the current spec, though it only works in Firefox. The code used here, while it does work, I thought was part of the original version of the spec. Also, worth mentioning is that you are *supposed* to pass in JavaScript object like in your example. Microsoft’s IE blog has examples where a string is passed in. I’ve not tested support on this across browsers, but it’s worth mentioning.

    I literally cannot tell you how many hours the whole “Store the initial content so we can revisit it later” issue turned out to be an issue for me. It seems unintuitive to me that the default state that you come to is not in the history stack.

    I’m trying the demo page on Internet Explorer 9 and I can’t tell any difference to Chrome so it seems to work.

    I’ll be using this article for a future project, for sure. Thank you!

    thank you for sharing your experience, very informative.

    Could you please elaborate on what you did on the server to handle the fake URLs? Are they manual redirects you inserted, or automatic rewrites? How are they converted?

    Thank you so much!

    In the mean time, I advanced a bit on that same subject. If your web server is Apache, you can configure it to use mod_rewrite, which allows to convert user (or crawler) typed URLs into other server side URLs:

    This is done by adding a number of rules in the .htaccess at the root of your website.

    Literally, just released my new site which makes use of this technique. It works beautifully!

    It’s nice to (maybe) be able to do away with hashes and hashbangs on future ajax-based sites.

    I’m really looking forward to seeing how this gets used as it’s adopted more widely.

    The only issues arise (as is often the case) with cross-browser implementations of this. The history API may be supported by the browsers you mentioned but with varying degrees of success.

    Check out History.js (note the capital ‘H’) by Ben Lupton here:https://github.com/balupton/History.js/ which offers a means to use HTML5 history states while accounting for craoos browser inconsistencies.

    Again, great article. Really gets down to the underlying principles.

    This is great, but if it doesn’t work on IE9 or below it’s pretty useless for production sites currently (without lots of messy hacks and fallbacks!)

    @Raphael + Eric:

    My apologises for the late reply! For the purposes of the demo, I used a very basic mod_rewrite and PHP setup.

    RewriteRule ^(fluffy|socks|whiskers|bob)$ index.php?p=$1

    The above rewrite rule masks the demo URLs and passes it into a single PHP file with a query string of what cat the user is attempting to view. The PHP file then checks $_GET["p"] is valid (always sanitise and check your input as appropriate), then using the pre-defined variables I have set for that cat.

    If this were a real application, the requested path could be used to construct database queries (sanitised of course) to pull in more dynamic content. CMS like WordPress use something like this for their “clean URL” implementation.

    Hope this helps.

    Would it be possible to see that htaccess file closer. I understand everything going on here, within the history api part, except the mod_rewrite. Do you actually have more pages living somewhere for each of these different cats? Refreshing the page after you click a few of the cats returns a page not found error. This has to do with the htaccess part that I am missing, right? Thanks.

    Despite my comment above about poor browser support I decided to switch from hashed URLs (/#/slug) to HTML5 history for http://goproheroes.com and decided to just fall back to normal page loading for IE9 and below using:

    function supports_history_api() {
    return !!(window.history && history.pushState);
    }

    Thanks Mike, your demo helped me out. I had my attempt a bit more complicated than it needed to be.

    However, I’m trying to track and detect when the user steps forward and back through the history so I can add appropriate transitions to my page. Unfortunately, the history API doesn’t let you know if a forward or back button was clicked on a popstate event. That would be really helpful.

    I’m thinking that a cookie might be the only way to attempt to track the order. Saving a previous variable in the state object complicated things and caused browser issues.

    Adding to the list,
    thanks Mike!

    Those adorable kitten’s helped me setup some pushing and popping functions on the soon-to-be released new version of my site!

    Thanks for the tut!

    In your clickhandler function you have something wrong in your post code (it’s ok on kittieland though):

    1. The event object is declared on the arguments as “e”, not “event”.

    2. There is no updateContent(); anywhere! I had to check your working source to see if I was doing something wrong.

    But wait, there’s more! …some updates too:

    3. Chrome 19+ starts to mingle with the state property of the event and stuff.

    As a tip: I used a lame setTimeout() to bind the event listener in order to skip Chrome’s eagerness to pop its state.

    До появления HTML5 единственное, что мы не могли контролировать и управлять (без перезагрузки контента или хаков с location.hash) - это история одного таба. С появлением HTML5 history API все изменилось - теперь мы можем гулять по истории (раньше тоже могли), добавлять элементы в историю, реагировать на переходы по истории и другие полезности. В этой статье мы рассмотрим HTML5 History API и напишем простой пример, иллюстрирующий его возможности.

    Основные понятия и синтаксис History API опирается на один DOM интерфейс - объект History. Каждый таб имеет уникальный объект History, который находится в window.history . History имеет несколько методов, событий и свойств, которыми мы можем управлять из JavaScript. Каждая страница таба(Document object) представляет собой объект коллекции History. Каждый элемент истории состоит из URL и/или объекта состояния (state object), может иметь заголовок (title), Document object, данные форм, позиция скролла и другую информацию, связанную со страницей.

    Основные методы объекта History:

  • window.history.length: Количество записей в текущей сессии истории
  • window.history.state: Возвращает текущий объект истории
  • window.history.go(n) : Метод, позволяющий гулять по истории. В качестве аргумента передается смещение, относительно текущей позиции. Если передан 0, то будет обновлена текущая страница. Если индекс выходит за пределы истории, то ничего не произойдет.
  • window.history.back() : Метод, идентичный вызову go(-1)
  • window.history.forward() : Метод, идентичный вызову go(1)
  • window.history.pushState(data, title [, url]) : Добавляет элемент истории.
  • window.history.replaceState(data, title [, url]) : Обновляет текущий элемент истории
  • Для перехода на 2 шага назад по истории можно использовать:
    history.go(-2)
    Для добавления элементов истории мы можем использовать history.pushState:
    history.pushState({foo: "bar"}, "Title", "/baz.html")
    Для изменения записи истории мы можем использовать history.replaceState:
    history.replaceState({foo: "bat"}, "New Title") Живой пример Теперь мы знаем основы, давайте посмотрим на живой пример. Мы будем делать веб файловый менеджер, который позволит вам найти URI выбранного изображения(). Файловый менеджер использует простую файловую структуру, написанную на JavaScript. Когда вы выбираете файл или папку картинка динамически обновляется.

    Мы используем data-* атрибуты для хранения заголовка каждой картинки и используем свойство dataset для получения этого свойства:

  • crab2.png

  • Чтобы все работало быстро мы подгружаем все картинки и обновляем атрибут src динамически. Это ускорение создает одну проблему - оно ломает кнопку назад, поэтому вы не можете переходить по картинками вперед или назад.

    HTML5 history приходит на помощь! Каждый раз когда мы выбираем файл создается новая запись истории и location документа обновляется (оно содержит уникальный URL картинки). Это означает, что мы можем использовать кнопку назад для обхода наших изображений, в то время как в строке адреса у нас будет прямая ссылка на картинку, которую мы можем сохранить в закладки или отправить кому-либо.

    Код У нас есть 2 дива. Один содержит структуру папок, другой содержит текущую картинку. Все приложение управляется с помощью JavaScript. В будут освещены только самые важные моменты. Исходный код примера очень короткий (порядка 80 строк) посмотрите его после прочтения всей статьи.

    Метод bindEvents навешивает обработчики для события popstate , который вызывается, когда пользователь переходит по истории и позволяет приложению обновлять свое состояние.
    window.addEventListener("popstate", function(e){ self.loadImage(e.state.path, e.state.note); }, false);
    Объект event , который передается в обработчик события popstate имеет свойство state - это данные, которые мы передали в качестве первого аргумента pushState или replaceState .

    Мы навешиваем обработчик на событие click на див, который представляет нашу файловую структуру. Используя делегацию событий, мы открываем или закрываем папку или загружаем картинку (с добавлением записи в историю). Мы смотрим на className родительского элемента для того, чтобы понять на какой из элементов мы нажали:
    - Если это папка мы открываем или закрываем её
    - Если это картина, то мы показываем её и добавляем элемент истории

    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.textContent); } }, false);
    Метод, который изменяет содержимое картинки и обновляет её подпись очень прост:
    loadImage: function(path, note){ img.src = path; h2.textContent = note; }
    Мы получили простое приложение , демонстрирующее возможности обновленного интерфейса объекта History . Мы используем pushState для добавления элемента истории и событие popstate для обновления содержимого страницы. Кроме этого при клике на картинку мы получаем в адресной строке её действительный адрес, который мы можем сохранить или отправить кому-нибудь.

    Когда можно будет использовать? Firefox 4+
    Safari 5+
    Chrome 10+
    Opera 11.5+
    iOS Safari 4.2+
    Android 2.2+
    IE ???
    Список браузеров , поддерживающих history API

    На этом уроке мы познакомимся с объектом history , который отвечает за кнопки "Назад" и "Вперёд", расположенные в окне браузера.

    Назначение объекта history

    Объект history отвечает за историю переходов, которые пользователь совершил в переделах одного окна или вкладки браузера. Эти переходы браузер сохраняет в сессию истории текущего окна (вкладки) и пользователь с помощи кнопки "Назад" всегда может вернуться на предыдущие страницы. Кроме кнопки "Назад" пользователю доступна ещё кнопка "Вперёд", которая предназначена для того, чтобы пользователь мог вернуться обратно на страницы, с которых он ушел с помощью кнопки "Назад". Таким образом, объект history отвечает за 2 эти кнопки, и позволять не только имитировать их нажатие, но добавлять и изменять записи в истории, перехватывать события при нажатии на эти кнопки и др.

    Например: В некотором окне (вкладке) браузера пользователь изначально открыл страницу 1. Просмотрев эту страницу, пользователь нажал в ней на некоторую ссылку и перешёл на страницу 2. На второй странице пользователь снова нажал на ссылку и перешёл на страницу 3. В результате сессия истории для этого окна (вкладки) будет состоять из 3 элементов.

    На текущий момент для пользователя доступна кнопка "Назад". При нажатии на эту кнопку пользователь может вернуться на страницу 2.

    В этот момент времени для пользователя становится доступны кнопки "Назад" и "Вперёд". При нажатии на кнопку "Назад" пользователь может вернуться на страницу 1, а при нажатии на кнопку "Вперёд" - на страницу 3. Таким образом, пользователь с помощью кнопок "Назад" и "Вперёд" может перемещаться по истории внутри этого окна (вкладки).

    Каждый элемент в сессии состоит из:

    • data - это некоторые данные, которые можно связать с определённым элементом истории. В основном они используются для того чтобы восстановить состояние динамической страницы при переходе к ней с помощью кнопки "Назад" или "Вперёд". Т.е. сначала Вы сохраняете состояние страницы, а точнее динамических её блоков, которые загружаются с помощью технологии AJAX, в data . А потом, когда пользователь переходит к ней с помощью кнопки "Назад" или "Вперёд", Вы можете восстановить состояние этой страницы, а точнее этих динамических блоков (т.к. одного URL не достаточно) с помощью информации, сохранённой в data .
    • title - название пункта истории. В настоящее время большинство браузеров не поддерживают возможность установления названия пункта с помощью JavaScript. Браузеры в качестве названия пункта истории используют название страницы, т.е. текст, расположенный между открывающим и закрывающим тегами HTML страницы.
    • url - URL адрес страницы.
    Свойства, методы и события объекта history

    В качестве примера рассмотрим работу с объектом history в консоли браузера:

  • Откроем вкладку в браузере и введём в адресной строке http://www.yandex.ru/ и нажмём Enter .
  • В этой же вкладке в адресной строке введём http://getbootstrap.com/ и нажмём опять Enter . Если посмотреть на кнопку "Назад", то он стала активной и позволяет перейти на один шаг назад, т.е. на страницу http://www.yandex.ru/ . Кроме этого можно увидеть список элементов истории, если нажать правой кнопкой мыши на кнопку "Назад".
  • Откроем консоль (клавиша F12 в браузере, вкладка "Консоль") и поработаем с историей с помощью JavaScript:
    • Узнаем количество элементов в истории: history.length ;
    • Добавим новый элемент в историю: history.pushState(null,null,"http://getbootstrap.com/css/");
    • Перезагрузим страницу с помощью объекта history: history.go(0);
    • Для примера заменим текущий элемент истории и свяжем с ним строку "Привет":
    • history.replaceState("Привет",null,"http://getbootstrap.com/javascript/");
    • Получим данные связанные с этим элементом истории: history.state;
    • Перейдём на 2 шага назад по истории, т.е. на страницу http://www.yandex.ru/ : history.go(-2);



    © 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows