Статьи

Введение в API истории HTML5

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

Благодаря API истории HTML5 мы можем лучше управлять историей браузера. Например, у нас есть способ добавить запись в историю или изменить URL в адресной строке, не обновляя страницу.

В этой статье мы узнаем, почему появился API истории HTML5. До того, как этот API существовал, мы часто использовали хеш-значения для изменения содержимого страницы, особенно для тяжелых одностраничных приложений, поскольку изменение URL было невозможно без обновления страницы. Кроме того, при изменении значения хеш-функции для URL-адреса он не вносит никаких изменений в историю браузера.

Теперь, однако, обе эти вещи доступны с помощью API истории HTML5, и это позволяет разрабатывать одностраничные приложения со сложными сценариями без использования хеш-значений. Это также позволяет нам создавать приложения в SEO-дружественной манере. Кроме того, этот метод позволяет нам уменьшить пропускную способность — но как?

В этой статье мы будем разрабатывать одностраничное приложение с этим API, чтобы продемонстрировать именно это.

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

Обратите внимание, что вам нужно выполнить некоторое кодирование на стороне сервера для доставки только частичных ресурсов вместо полного содержимого страницы.

На момент написания этой статьи поддержка браузера для HTML5 History API была достаточно хорошей, мы можем посмотреть ее статус здесь . Эта ссылка даст вам представление о поддерживаемых браузерах, но всегда полезно обнаружить поддержку конкретной функции перед ее использованием.

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

1
return !!(window.history && history.pushState);

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

Если вы используете Modernizr, то вы должны использовать следующий код:

1
2
3
if (Modernizr.history) {
    // History API Supported
}

Если ваш браузер не поддерживает API истории, вы можете использовать полифилы history.js .

HTML5 предоставляет два новых метода:

  1. history.pushState()
  2. history.replaceState()

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

pushState и replaceState ожидают одинакового количества параметров, как replaceState ниже:

  1. state может хранить строку JSON и будет доступен для события popstate .
  2. title — это параметр, который пока игнорируется большинством браузеров, поэтому лучше установить его на null на сегодня.
  3. url может представлять любой URL. Он будет обновлен по адресу браузера, и ему будет все равно, существует этот URL или нет. Самое главное, он не перезагрузит вашу веб-страницу.

Основные различия между этими методами заключаются в том, что pushState добавит новую запись в стек истории, а replaceState заменит текущее значение истории вместо добавления нового. Если вы все еще запутались в обоих этих методах, давайте продемонстрируем один и тот же случай на лучшем примере.

Предположим, у нас есть стеки из двух блоков с метками 1 и 2, а у вас в руке блок с меткой 3. Теперь, когда мы выполняем pushState , блок 3 будет добавлен в существующий стек, так что в стеке будет 3 блока.

Теперь возьмем тот же стек с двумя блоками и еще одним в вашей руке. Когда мы выполняем replaceState , он выберет блок 2 из стека и поместит блок 3. Таким образом, количество значений истории останется неизменным. pushState , с другой стороны, увеличивает количество историй на единицу.

На рисунке ниже показана та же демонстрация.

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

Хотя вы можете ожидать popstate при pushState replaceState методам pushState или replaceState , но в действительности это не так. Вместо этого popstate будет срабатывать, когда вы перемещаетесь по записи истории сеанса, нажимая кнопки назад или вперед или используя методы history.go или history.back .

В браузерах WebKit событие popstate будет запускаться после события onload документа, но Firefox и IE не имеют такого поведения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class=»container»>
    <div class=»row»>
        <ul class=»nav navbar-nav»>
            <li><a href=»home.html» class=»historyAPI»>Home</a></li>
            <li><a href=»about.html» class=»historyAPI»>About</a></li>
            <li><a href=»contact.html» class=»historyAPI»>Contact</a></li>
        </ul>
    </div>
    <div class=»row»>
        <div class=»col-md-6″>
            <div class=»well»>
                Click on Links above to see history API usage using <code>pushState</code> method.
            </div>
        </div>
        <div class=»row»>
            <div class=»jumbotron» id=»contentHolder»>
                <h1>Home!</h1>
                <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
            </div>
        </div>
    </div>
</div>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<script type=»text/javascript»>
    jQuery(‘document’).ready(function(){
         
        jQuery(‘.historyAPI’).on(‘click’, function(e){
            e.preventDefault();
            var href = $(this).attr(‘href’);
             
            // Getting Content
            getContent(href, true);
             
            jQuery(‘.historyAPI’).removeClass(‘active’);
            $(this).addClass(‘active’);
        });
         
    });
     
    // Adding popstate event listener to handle browser back button
    window.addEventListener(«popstate», function(e) {
         
        // Get State value using e.state
        getContent(location.pathname, false);
    });
     
    function getContent(url, addEntry) {
        $.get(url)
        .done(function( data ) {
             
            // Updating Content on Page
            $(‘#contentHolder’).html(data);
             
            if(addEntry == true) {
                // Add History Entry using pushState
                history.pushState(null, null, url);
            }
             
        });
    }
</script>

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

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

Этот API оказал большое влияние на работу нашего веб-приложения. Он убрал зависимость от значений хеш-функции в URL, чтобы упростить создание эффективного, оптимизированного для SEO, одностраничного приложения.

Это действительно хороший API, не так ли?