Адрес страницы вперед javascript history forward 1. Управление историей просмотров. Назначение объекта history
В данной подборке собраны самые лучшие и качественные CSS фишки. Тут Вы сможете встретить различные и удивительные демо примеры и техники от знаменитых верстальщиков и дизайнеров, которые стараются доказать, что сейчас возможно сделать практически всё только на чистом CSS. Так же Вы тут сможете встретить несколько уроков в которых подробно рассказывается как сделать подобное творение. Надеюсь, что эта подборка окажется Вам полезной.
CSS 3D облака
В этом демо Вы сможете создавать и редактировать причудливые облака в 3D. Данные облака на CSS дают понять нам, что возможности веб технологий практически безграничны.
Логотипы на чистом CSS
Это примеры логотипов сделанных только на чистом CSS. Вы только вдумайтесь, при создании не использовались изображения. Это просто нечто.
Урок о том как создать стильные прогресс бары на чистом CSS и с анимацией. Также Вы можете посмотреть пример и скачать исходники.
Анимация — Animate.css
Самый популярный проект CSS анимации в интернете на сегодняшний день. И наверное самый простой и качественный, и к тому же бесплатный.
Индикаторы загрузки — Spinkit
Скажу честно данные индикаторы уже встречались на блоге, но мне кажется что их стоит ещё раз Вам показать. Так как это самые красивые индикаторы в интернете на CSS.
Кнопки
Сейчас кнопками на CSS уже тяжело удивить, но это довольно достойный вариант
Генератор для создания переключателей
Небольшое и качественное интернет приложение, с помощью которого Вы сможете создать красивые переключатели для использования на сайте.
Всплывающие подсказки
CSS библиотека бесплатных всплывающих подсказок — Hint.css
Цветовые схемы
Схемы цветов для людей, которые не любят копаться в коде
16
ответов
Короткий ответ: вы не можете.
Технически существует точный способ проверки подлинности:
History.previous
Однако это не сработает.
Проблема в том, что в большинстве браузеров это считается нарушением безопасности и обычно просто возвращает undefined
.. p >
History.length
Это свойство, которое другие предложили... Однако
длина не работает полностью, поскольку в истории вы не указываете , где
. Кроме того, он не всегда начинается с того же номера. Например, браузер, не настроенный на целевую страницу, начинается с 0, тогда как другой браузер, который использует страницу перевязки, начинается с 1.
History.back();
History.go(-1);
и он просто ожидал, что если вы не сможете вернуться, то щелчок по ссылке ничего не делает.
Мой код позволяет браузеру вернуться на одну страницу, и если это не удается, он загружает резервный URL-адрес. Он также обнаруживает изменения хэштегов.
Если кнопка "Назад" недоступна, резервный url будет загружен через 500 мс, поэтому браузер имеет достаточно времени для загрузки предыдущей страницы. Загрузка обратного URL сразу после window.history.go(-1); приведет к тому, что браузер будет использовать резервный URL-адрес, потому что js script еще не остановился.
Function historyBackWFallback(fallbackUrl) {
fallbackUrl = fallbackUrl || "/";
var prevPage = window.location.href;
window.history.go(-1);
setTimeout(function(){
if (window.location.href == prevPage) {
window.location.href = fallbackUrl;
}
}, 500);
}
это похоже на трюк:
Function goBackOrClose() {
window.history.back();
window.close();
//or if you are not interested in closing the window, do something else here
//e.g.
theBrowserCantGoBack();
}
Вызов history.back(), а затем window.close(). Если браузер сможет вернуться в историю, он не сможет перейти к следующему утверждению. Если он не сможет вернуться, он закроет окно.
Однако, обратите внимание, что если страница была достигнута, набрав URL-адрес, то firefox не позволит script закрыть окно.
Вы не можете напрямую проверить, доступна ли кнопка "Назад". Вы можете посмотреть history.length>0 , но это будет верно, если страницы впереди и на текущей странице. Вы можете только быть уверены, что кнопка "Назад" непригодна, если history.length===0 .
Если это не достаточно хорошо, обо всем, что вы можете сделать, это позвонить history.back() и, если ваша страница все еще загружена, кнопка "Назад" недоступна! Конечно, это означает, что если кнопка "Назад" доступна, вы просто перешли от страницы. Вам не разрешено отменять навигацию в onunload , поэтому обо всем, что вы можете сделать, чтобы остановить обратное на самом деле, это вернуть что-то из onbeforeunload , что приведет к появлению большого раздражающего приглашения. Это не стоит.
На самом деле обычно это действительно плохая идея делать что-либо с историей. Навигация по истории - для браузера Chrome, а не для веб-страниц. Добавление ссылок "вернуться" обычно вызывает больше недоумения пользователей, чем это стоит.
Вот как я это сделал.
Я использовал событие "beforeunload"
, чтобы установить логическое значение. Затем я установил тайм-аут, чтобы посмотреть, запускается ли "beforeunload".
Кажется, он работает в основных браузерах (тестировал FF, Chrome, IE11 до сих пор).
В моих проектах есть фрагмент:
Function back(url) {
if (history.length > 2) {
// if history is not empty, go back:
window.History.back();
} else if (url) {
// go to specified fallback url:
window.History.replaceState(null, null, url);
} else {
// go home:
window.History.replaceState(null, null, "/");
}
}
К вашему сведению: я использую History.js для управления историей браузера.
Зачем сравнивать history.length с номером 2?
Потому что стартовая страница Chrome считается первым элементом в истории браузера.
Существует несколько возможностей history.length и поведения пользователя:
Пользователь открывает новую пустую вкладку
в браузере, а затем запускает страницу. history.length = 2 и мы хотим отключить back() в этом случае, потому что пользователь перейдет на пустую вкладку.
Пользователь открывает страницу в новой вкладке
, щелкая ссылку где-то раньше. history.length = 1 и снова мы хотим отключить метод back() .
И, наконец, пользователь попадает на текущую страницу после перезагрузки нескольких страниц
. history.length > 2 и теперь back() можно включить.
Примечание:
я пропускаю случай, когда пользователь попадает на текущую страницу после нажатия на ссылку с внешнего сайта без target="_blank" .
Примечание 2:
document.referrer пуст, когда вы открываете веб-сайт, вводя его адрес, а также когда веб-сайт использует ajax для загрузки подстраниц, поэтому я прекратил проверку этого значения в первом случае.
history.length бесполезен, так как он не показывает, может ли пользователь вернуться в историю.
Также разные браузеры используют начальные значения 0 или 1 - это зависит от браузера.
Рабочее решение - использовать событие $(window).on("beforeunload" , но я не уверен, что он будет работать, если страница загружается через ajax и использует pushState для изменения истории окна.
Итак, я использовал следующее решение:
Var currentUrl = window.location.href;
window.history.back();
setTimeout(function(){
// if location was not changed in 100 ms, then there is no history back
if(currentUrl === window.location.href){
// redirect to site root
window.location.href = "/";
}
}, 100);
Будьте осторожны с window.history.length потому что оно также содержит записи для window.history.forward()
Таким образом, вы можете иметь window.history.length с более чем 1 записями, но без записей истории. Это означает, что ничего не произойдет, если вы запустите window.history.back()
Я придумал следующий подход. Он использует событие onbeforeunload, чтобы определить, покидает ли браузер страницу или нет. Если в определенный промежуток времени он не будет перенаправлен на резервную копию.
Var goBack = function goBack(fallback){
var useFallback = true;
window.addEventListener("beforeunload", function(){
useFallback = false;
});
window.history.back();
setTimeout(function(){
if (useFallback){ window.location.href = fallback; }
}, 100);
}
Вы можете вызвать эту функцию, используя goBack("fallback.example.org") .
window.location.pathname выдаст вам текущий URI. Например, https://domain/question/1234/i-have-a-problem выдаст /question/1234/i-have-a-problem . См. Документацию о window.location
Затем вызов функции split() даст нам все фрагменты этого URI. поэтому, если мы возьмем наш предыдущий URI, у нас будет что-то вроде ["", "question", "1234", "i-have-a-problem"] . См. Документацию о String.prototype.split() для получения дополнительной информации.
Вызов filter() здесь для того, чтобы отфильтровать пустую строку, созданную обратной косой чертой. Он будет возвращать только фрагмент URI, длина которого больше 1 (непустая строка). Таким образом, у нас будет что-то вроде ["question", "1234", "i-have-a-question"] . Это можно было бы написать так:
См. Документацию о Array.prototype.filter() и назначении Destructuring для получения дополнительной информации.
Теперь, если пользователь пытается вернуться, находясь на https://domain/ , мы не будем запускать оператор if и поэтому не window.history.back() вызывать метод window.history.back() чтобы пользователь оставался на нашем веб-сайте. Этот URL будет эквивалентен который имеет длину 0 , а 0 > 0 - false. Следовательно, молча терпит неудачу. Конечно, вы можете что-то зарегистрировать или выполнить другое действие, если хотите.
"use strict";
function previousPage() {
if (window.location.pathname.split("/").filter(({ length }) => length > 0).length > 0) {
window.history.back();
} else {
alert("You cannot go back any further...");
}
}
Ограничения
Конечно, это решение не будет работать, если браузер не поддерживает History API . Проверьте документацию, чтобы узнать больше об этом, прежде чем использовать это решение.
Using history.pushState() changes the referrer that gets used in the HTTP header for XMLHttpRequest objects created after you change the state. The referrer will be the URL of the document whose window is this at the time of creation of the XMLHttpRequest object.
Example of pushState() method
Suppose http://mozilla.org/foo.html
executes the following JavaScript:
This will cause the URL bar to display http://mozilla.org/bar.html
, but won"t cause the browser to load bar.html or even check that bar.html exists.
Suppose now that the user navigates to http://google.com, then clicks the Back button. At this point, the URL bar will display http://mozilla.org/bar.html and history.state will contain the stateObj . The popstate event won"t be fired because the page has been reloaded. The page itself will look like bar.html.
If we click Back again, the URL will change to http://mozilla.org/foo.html
, and the document will get a popstate event, this time with a null state object. Here too, going back doesn"t change the document"s contents from what they were in the previous step, although the document might update its contents manually upon receiving the popstate event.
The pushState() method
pushState() takes three parameters: a state object, a title (which is currently ignored), and (optionally) a URL. Let"s examine each of these three parameters in more detail:
state object
- The state object is a JavaScript object which is associated with the new history entry created by pushState() . Whenever the user navigates to the new state, a popstate event is fired, and the state property of the event contains a copy of the history entry"s state object.
The state object can be anything that can be serialized. Because Firefox saves state objects to the user"s disk so they can be restored after the user restarts the browser, we impose a size limit of 640k characters on the serialized representation of a state object. If you pass a state object whose serialized representation is larger than this to pushState() , the method will throw an exception. If you need more space than this, you"re encouraged to use sessionStorage and/or localStorage .
title
- Firefox currently ignores this parameter, although it may use it in the future. Passing the empty string here should be safe against future changes to the method. Alternatively, you could pass a short title for the state to which you"re moving.
URL
- The new history entry"s URL is given by this parameter. Note that the browser won"t attempt to load this URL after a call to pushState() , but it might attempt to load the URL later, for instance after the user restarts the browser. The new URL does not need to be absolute; if it"s relative, it"s resolved relative to the current URL. The new URL must be of the same origin as the current URL; otherwise, pushState() will throw an exception. This parameter is optional; if it isn"t specified, it"s set to the document"s current URL.
Note:
In Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) through Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the passed object is serialized using JSON. Starting in Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the object is serialized using the structured clone algorithm . This allows a wider variety of objects to be safely passed.
In a sense, calling pushState() is similar to setting window.location = "#foo" , in that both will also create and activate another history entry associated with the current document. But pushState() has a few advantages:
The new URL can be any URL in the same origin as the current URL. In contrast, setting window.location keeps you at the same document only if you modify only the hash.
You don"t have to change the URL if you don"t want to. In contrast, setting window.location = "#foo"; creates a new history entry only if the current hash isn"t #foo .
You can associate arbitrary data with your new history entry. With the hash-based approach, you need to encode all of the relevant data into a short string.
If title is subsequently used by browsers, this data can be utilized (independent of, say, the hash).
Note that pushState() never causes a hashchange event to be fired, even if the new URL differs from the old URL only in its hash.
Specifications
Specification
Status
Comment
HTML Living Standard
Living Standard
No change from HTML5 .
HTML5 The definition of "History" in that specification.
Recommendation
Initial definition.
Browser compatibility
The compatibility table on this page is generated from structured data. If you"d like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
Update compatibility data on GitHub
Desktop
Mobile
Chrome
Edge
Firefox
Internet Explorer
Opera
Safari
Android webview
Chrome for Android
Edge Mobile
Firefox for Android
Opera for Android
Safari on iOS
Samsung Internet
History
Chrome
Full support
Yes
Edge
Full support
Yes
Firefox
Full support
Yes
IE
Full support
Yes
Opera
Full support
Yes
Safari
Full support
Yes
Samsung Internet Android
?
back
Chrome
Full support
Yes
Edge
Full support
12
Firefox
Full support
Yes
IE
?
Opera
?
Safari
?
WebView Android
Full support
Yes
Chrome Android
Full support
Yes
Edge Mobile
?
Firefox Android
Full support
Yes
Opera Android
?
Safari iOS
?
Samsung Internet Android
?
forward
Chrome
Full support
Yes
Edge
Full support
12
Firefox
Full support
Yes
IE
?
Opera
?
Safari
?
WebView Android
Full support
Yes
Chrome Android
Full support
Yes
Edge Mobile
?
Firefox Android
Full support
Yes
Opera Android
?
Safari iOS
?
Samsung Internet Android
?
go
Chrome
Full support
Yes
Edge
Full support
12
Firefox
Full support
Yes
IE
?
Opera
?
Safari
?
WebView Android
Full support
Yes
Chrome Android
Full support
Yes
Edge Mobile
?
Firefox Android
Full support
Yes
Opera Android
?
Safari iOS
?
Samsung Internet Android
?
length
Chrome
Full support
Yes
Edge
Full support
12
Firefox
Full support
Yes
IE
?
Opera
?
Safari
?
WebView Android
Full support
Yes
Chrome Android
Full support
Yes
Edge Mobile
?
Firefox Android
Full support
Yes
Opera Android
?
Safari iOS
?
Samsung Internet Android
?
pushState
Chrome
Full support
5
Edge
Full support
12
Firefox
Full support
4
Notes
Full support
4
Notes
Notes
IE
Full support
10
Opera
Full support
11.5
Safari
Full support
5
WebView Android
Full support
Yes
Chrome Android
Full support
Yes
Edge Mobile
Full support
Yes
Firefox Android
Full support
Yes
Opera Android
Full support
Yes
Samsung Internet Android
?
replaceState
Chrome
Full support
5
Edge
Full support
12
Firefox
Full support
4
Notes
Full support
4
Notes
Notes
In Firefox 2 through 5, the passed object is serialized using JSON. Starting in Firefox 6, the object is serialized using . This allows a wider variety of objects to be safely passed.
IE
Full support
10
Opera
Full support
11.5
Safari
Full support
5
WebView Android
Full support
Yes
Chrome Android
Full support
Yes
Edge Mobile
Full support
Yes
Firefox Android
Full support
Yes
Opera Android
Full support
Yes
Safari iOS
Full support
4.3
Samsung Internet Android
?
scrollRestoration
Chrome
Full support
46
Edge
No support
No
Firefox
Full support
46
IE
No support
No
Opera
Full support
33
Safari
Full support
Yes
WebView Android
No support
No
Chrome Android
Full support
46
Edge Mobile
No support
No
Firefox Android
Full support
Yes
Opera Android
Full support
Yes
Safari iOS
Full support
Yes
Samsung Internet Android
?
state
Chrome
Full support
Yes
Edge
Full support
12
Firefox
Full support
Yes
IE
?
Opera
?
Safari
?
WebView Android
Full support
Yes
Chrome Android
Full support
Yes
Edge Mobile
?
Firefox Android
Full support
Yes
Opera Android
?
Safari iOS
?
Samsung Internet Android
?
Legend
Full support
Full support
No support
No support
Compatibility unknown
Compatibility unknown See implementation notes.
See implementation notes.
Перевод: Влад Мержевич
Адресная строка браузера это, пожалуй, наиболее чокнутая часть пользовательского интерфейса в мире. Адреса сайтов есть на рекламных щитах, на поездах и даже на уличных граффити. В сочетании с кнопкой «Назад» - наиболее важной кнопкой в браузере - у вас есть мощный способ двигаться вперед и назад через огромное множество взаимосвязанных ресурсов называемых вебом.
API истории HTML5 представляет собой стандартизированный способ манипулировать историей браузера через скрипт. Часть этого API - навигация по истории - была доступна в предыдущих версиях HTML. Новые части в HTML5 включают способ добавления записей в историю браузера, чтобы заметно изменить URL в адресной строке браузера (без переключения обновления страницы) и события, которые запускаются, когда эти записи удаляются из стека пользователя нажатием кнопки браузера «Назад». Это означает, что URL в адресной строке браузера может продолжать выполнять свою работу как уникальный идентификатор для текущего ресурса, даже в приложениях нагруженными скриптами, которые не всегда выполняют полное обновление страницы.
Почему
Почему бы вам вручную не изменять адресную строку браузера? В конце концов, простая ссылка может перейти на новый URL, этот способ работал в течение 20 лет. И он будет продолжать работать таким образом. Этот API не пытается подорвать веб. Как раз наоборот. В последние годы веб-разработчики нашли новые и увлекательные способы подрыва веба без какой-либо помощи со стороны новых стандартов. API истории HTML5 на самом деле предназначен для того, чтобы адреса продолжали быть полезными в веб-приложениях нагруженными скриптами.
Возвращаясь к изначальным принципам, что теперь делает URL? Он определяет уникальный ресурс. Вы можете указать ссылку напрямую, добавить ее в закладки, поисковые системы ее индексируют, вы можете скопировать и вставить ее, отправить по почте кому-то еще, кто может нажать ссылку и в конечном итоге увидит тот же ресурс, что и вы первоначально. Все эти прекрасные качества URL сохраняются.
Поэтому мы хотим, чтобы уникальные ресурсы имели уникальный URL. Но в то же время браузеры всегда имели фундаментальное ограничение: если вы измените URL, даже через скрипт, это включит запрос к удаленному веб-серверу и приведет к обновлению страницы. Это требует времени и ресурсов, что, кажется, особенно расточительно, когда вы перемещаетесь на страницу, которая в значительной степени похожа на текущую. Все на новой странице будет загружено, включая те части, которые точно такие же, как на текущей странице. Нет способа сказать браузеру изменить URL и загрузить только половину страницы.
API истории HTML5 позволяет сделать это. Вместо запуска полного обновления страницы вы можете использовать скрипт, который, в сущности, скачивает половину страницы. Эта иллюзия довольно хитрая для воплощения и потребует некоторых усилий с вашей стороны. Вы внимательно следите?
Скажем, у вас есть две страницы, страница А и страница Б. Две страницы на 90% идентичны и только 10% содержимого страниц различается. Пользователь переходит на страницу А, затем пытается перейти к странице Б. Но вместо запуска полного обновления страницы, вы прерываете эту навигацию и совершаете следующие шаги вручную:
Загружаете 10% из страницы Б, которые отличаются от страницы А (возможно с помощью XMLHttpRequest
). Это потребует некоторых серверных изменения в вашем веб-приложении. Вам нужно будет написать код, который возвращает только 10% от страницы Б, отличающихся от страницы А. Это может быть скрытый URL или параметр запроса, невидимый конечному пользователю.
Обмениваете измененное содержание (с использованием innerHtml
или других методов DOM). Вам также может понадобиться сбросить любой обработчик событий для элемента внутри обменного содержания.
Обновляете строку браузера с адресом страницы Б, используя особый метод из 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 в адресной строке браузера без запуска полного обновления страницы. В неподдерживаемых браузерах - или в действительности поддерживаемых браузерах, где пользователь отключил скрипты - ссылки просто работают как обычные ссылки, переводя вас на новую страницу с полным ее обновлением.
Это поднимает важный момент.
Профессор Маркап говорит
Если ваше веб-приложение потерпит неудачу в браузерах с отключенными скриптами, собака Якоба Нильсена придет к вам домой и насрет на ваш ковер.
Давайте обратимся к демо и посмотрим, как оно работает. Это соответствующий код для одной фотографии.
Ничего необычного здесь нет. Фотография это
внутри
, ссылки просто очередные элементы
и все завернуто в
Основная функция программы получить каждую из этих ссылок и передать ее функции addClicker()
, которая делает фактическую работу по созданию пользовательского обработчика click
.
Function setupHistoryClicks() {
addClicker(document.getElementById("photonext"));
addClicker(document.getElementById("photoprev"));
}
Функция swapPhoto()
выполняет первые два шага из трех нашей трехэтапной иллюзии. В первой половине функции swapPhoto()
берется часть адреса ссылки - casey.html, adagio.html и др. - и строится URL в скрытой странице, которая содержит только код, требуемый для следующей фотографии.
Function swapPhoto(href) {
var req = new XMLHttpRequest();
req.open("GET",
"gallery/" +
href.split("/").pop(),
false);
req.send(null);
Этот образец разметки возвращает http://diveintohtml5.info/examples/history/gallery/casey.html (вы можете проверить это в браузере, вставив URL напрямую).
Выглядит знакомо? Так и должно быть. Это тот же основной код, что у исходной страницы, используемый для отображения первой фотографии.
Вторая половина функции swapPhoto()
выполняет второй шаг нашей трехэтапной иллюзии: вставляет этот новый загруженный код в текущую страницу. Помните, что существует
Также обратите внимание на вызов setupHistoryClicks()
. Это необходимо, чтобы сбросить пользовательский обработчик событий click
для новых вставленных ссылок. Установка innerHtml
стирает любые следы старых ссылок и их обработчиков событий.
Теперь давайте вернемся к функции addClicker()
. После успешной смены фотографии есть еще один шаг в нашей трехэтапной иллюзии: установить URL в адресной строке браузера без перезагрузки страницы.
History.pushState(null, null, link.href);
Функция history.pushState()
содержит три параметра:
state
может быть любой структурой данных JSON. Он передается обратно обработчику событий popstate
, о котором вы узнаете чуть позже. Нам не нужно следить за state
в этой демонстрации, так что я оставил его как null
.
title
может быть любой строкой. Этот параметр в настоящее время не используется основными браузерами. Если вы хотите установить заголовок страницы, вы должны сохранить его в аргументе state
и установить вручную в popstate
.
url
может быть, ну, любым URL. Это URL, который должен отображаться в адресной строке браузера.
Вызов history.pushState
немедленно изменит URL в адресной строке браузера. Так это конец иллюзии? Ну, не совсем. Нам еще нужно сказать о том, что происходит, когда пользователь нажимает важную кнопку «Назад».
Обычно, когда пользователь переходит на новую страницу (с полным обновлением страницы), браузер помещает новый URL в стек истории, загружает и отрисовывает новую страницу. Когда пользователь нажимает кнопку «Назад», браузер сдвигает одну страницу в стеке истории и перерисовывает предыдущую страницу. Но что происходит теперь, когда вы сделали короткое замыкание этой навигации, чтобы избежать полного обновления страницы? Итак, вы поддельно «двинулись вперед» на новый URL, так что теперь необходимо также поддельно «двинуться назад» к предыдущему URL. И ключ к поддельному «двинуться назад» в событии popstate
.
После того как вы использовали функцию history.pushState()
для смещения поддельного URL в стеке истории браузера, когда пользователь нажимает кнопку «Назад», в браузере срабатывает событие popstate
на объекте window
. Это ваш шанс завершить иллюзию раз и навсегда. Потому что не достаточно сделать исчезновение чего-то, вы также должны вернуть его.
В этой демонстрации «вернуть его» так же просто, как смена исходной фотографии, которую мы делаем с помощью вызова swapPhoto()
в текущей локации. К тому времени popstate
будет вызван, URL отображается в адресной строке браузера как измененный на предыдущий URL. Кроме того, глобальное свойство location
уже был обновлено с предыдущим URL.
Чтобы помочь вам представить это, давайте пройдем по шагам через всю иллюзию от начала до конца:
Пользователь загружает http://diveintohtml5.info/examples/history/fer.html , смотрит историю и фотографию Фер.
Вместо перехода на http://diveintohtml5.info/examples/history/casey.html с полной перезагрузкой страницы, пользовательский обработчик click
на элементе
перехватывает щелчок и выполняет собственный код.
Наш собственный обработчик click
вызывает функцию swapPhoto()
, которая создает объект XMLHttpRequest
для синхронной загрузки фрагмента HTML по адресу http://diveintohtml5.info/examples/history/gallery
/casey.html .
Функция swapPhoto()
устанавливает свойство innerHTML
обертке фотогалереи (элемент
Наконец, наш обработчик 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
для элемента
Иллюзия завершена. Все видимые доказательства (содержание страницы и URL в адресной строке) убеждают пользователя, что у него был переход вперед и назад на страницу. Но полного обновления страницы не происходит - все это было тщательно выполненной иллюзией.
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:
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:
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.
Часть вторая
: "Важнейшие характеристики каждого семейства процессоров Intel Core i3/i5/i7. Какие из этих чипов представляют особый интерес"
Введение
Сначала мы приведём...