РабоÑа Ñ History API
Ð HTML5 ÑÑали доÑÑÑÐ¿Ð½Ñ Ð¼ÐµÑÐ¾Ð´Ñ pushState() и replaceState() Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñей в иÑÑоÑии. ÐÑи меÑÐ¾Ð´Ñ ÑабоÑаÑÑ Ð² ÑоÑеÑании Ñ ÑобÑÑием onpopstate
Ðобавление и изменение запиÑей в иÑÑоÑии
pushState() позволÑÐµÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ referrer, коÑоÑÑй иÑполÑзÑеÑÑÑ Ð² HTTP-заголовке Ð´Ð»Ñ XMLHttpRequest обÑекÑов, ÑозданнÑÑ
поÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑоÑÑоÑниÑ. ÐнаÑением referrer бÑÐ´ÐµÑ URL докÑменÑа, окно коÑоÑого ÑвлÑеÑÑÑ this на Ð¼Ð¾Ð¼ÐµÐ½Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ XMLHttpRequest обÑекÑа.
ÐÑÐ¸Ð¼ÐµÑ Ð¼ÐµÑода pushState()
ÐÑедположим, на ÑÑÑаниÑе http://mozilla.org/foo.html вÑполнÑеÑÑÑ ÑледÑÑÑий JavaScript-код:
let stateObj = {
foo: "bar",
};
history.pushState(stateObj, "page 2", "bar.html");
Ð ÑезÑлÑÑаÑе ÑÑого в URL-ÑÑÑоке оÑобÑазиÑÑÑ Ð°Ð´ÑÐµÑ http://mozilla.org/bar.html, но бÑаÑÐ·ÐµÑ Ð½Ðµ бÑÐ´ÐµÑ Ð·Ð°Ð³ÑÑжаÑÑ ÑÑÑаниÑÑ bar.html и даже не бÑÐ´ÐµÑ Ð¿ÑовеÑÑÑÑ, ÑÑÑеÑÑвÑÐµÑ Ð»Ð¸ она..
ТепеÑÑ Ð¿Ñедположим, ÑÑо полÑзоваÑÐµÐ»Ñ Ð¿ÐµÑеÑÑл по адÑеÑÑ http://google.com и заÑем нажал на ÐºÐ½Ð¾Ð¿ÐºÑ "Ðазад". Ð ÑезÑлÑÑаÑе ÑÑого в URL бÑÐ´ÐµÑ Ð¾ÑобÑажаÑÑÑÑ http://mozilla.org/bar.html, а history.state бÑÐ´ÐµÑ ÑодеÑжаÑÑ stateObj. СобÑÑие popstate не бÑÐ´ÐµÑ Ð²Ñзвано, поÑколÑÐºÑ ÑÑÑаниÑа бÑла пеÑезагÑÑжена. Сама ÑÑÑаниÑа бÑÐ´ÐµÑ Ð²ÑглÑдеÑÑ ÐºÐ°Ðº bar.html.
ÐÑли полÑзоваÑÐµÐ»Ñ ÐµÑÑ Ñаз Ð½Ð°Ð¶Ð¸Ð¼Ð°ÐµÑ ÐºÐ½Ð¾Ð¿ÐºÑ "Ðазад", URL измениÑÑÑ Ð½Ð° http://mozilla.org/foo.html, а в докÑменÑе Ñнова пÑоизойдÑÑ ÑобÑÑие popstate, на ÑÑÐ¾Ñ Ñаз Ñ Ð¾Ð±ÑекÑом ÑоÑÑоÑниÑ, имеÑÑим знаÑение null. Ð ÑÑом ÑлÑÑае возвÑÐ°Ñ Ð½Ð°Ð·Ð°Ð´ Ñакже не менÑÐµÑ ÑодеÑжимое докÑменÑа, как и на пÑедÑдÑÑем Ñаге, Ñ
оÑÑ Ð´Ð¾ÐºÑÐ¼ÐµÐ½Ñ Ð¼Ð¾Ð¶ÐµÑ Ñам обновиÑÑ ÑÐ²Ð¾Ñ ÑодеÑжимое поÑле полÑÑÐµÐ½Ð¸Ñ ÑобÑÑÐ¸Ñ popstate.
ÐеÑод pushState()
ÐеÑод pushState() пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ ÑÑи паÑамеÑÑа: обÑÐµÐºÑ ÑоÑÑоÑниÑ, заголовок (в даннÑй Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð¸Ð³Ð½Ð¾ÑиÑÑеÑÑÑ) и (необÑзаÑелÑно) паÑамеÑÑ "URL".
ÐавайÑе более подÑобно ÑаÑÑмоÑÑим каждÑй и ÑÑÐ¸Ñ ÑÑÑÑ Ð¿Ð°ÑамеÑÑов.
- state object
-
ÐбÑÐµÐºÑ ÑоÑÑоÑÐ½Ð¸Ñ â ÑÑо JavaScript-обÑекÑ, ÑвÑзаннÑй Ñ Ð½Ð¾Ð²Ð¾Ð¹ запиÑÑÑ Ð² иÑÑоÑии, Ñозданной
pushState(). ÐÑÑкий Ñаз, когда полÑзоваÑÐµÐ»Ñ Ð¿ÐµÑÐµÑ Ð¾Ð´Ð¸Ñ Ðº Ð½Ð¾Ð²Ð¾Ð¼Ñ ÑоÑÑоÑниÑ, пÑоиÑÑ Ð¾Ð´Ð¸Ñ ÑобÑÑиеpopstate, а ÑвойÑÑвоstateÑÑого ÑобÑÑÐ¸Ñ ÑодеÑÐ¶Ð¸Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð¾Ð±ÑекÑа ÑоÑÑоÑÐ½Ð¸Ñ Ñ Ð·Ð°Ð¿Ð¸ÑÑми иÑÑоÑии.ÐбÑÐµÐºÑ ÑоÑÑоÑÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñем-Ñгодно, ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑеÑиализовано. ÐоÑколÑÐºÑ Firefox ÑÐ¾Ñ ÑанÑÐµÑ Ð¾Ð±ÑекÑÑ ÑоÑÑоÑÐ½Ð¸Ñ Ð½Ð° диÑке полÑзоваÑелÑ, ÑÑÐ¾Ð±Ñ Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ бÑло воÑÑÑановиÑÑ Ð¿Ð¾Ñле пеÑезапÑÑка бÑаÑзеÑа, Ð¼Ñ Ð½Ð°ÐºÐ»Ð°Ð´Ñваем огÑаниÑение в 640 ÑÑÑÑÑ Ñимволов на ÑеÑиализованное пÑедÑÑавление обÑекÑа ÑоÑÑоÑниÑ. ÐÑли Ð²Ñ Ð¿ÐµÑедаÑÑе обÑÐµÐºÑ ÑоÑÑоÑниÑ, ÑÑÑ ÑеÑиализованное пÑедÑÑавление болÑÑе ÑÑого знаÑениÑ, меÑод
pushState()вÑдаÑÑ Ð¸ÑклÑÑение. ÐÑли вам нÑжно Ñ ÑанилиÑе болÑÑего ÑазмеÑа, ÑледÑÐµÑ ÑаÑÑмоÑÑеÑÑ Ð¸ÑполÑзованиеsessionStorageи/илиlocalStorage. - title
-
Ðаголовок - вÑе бÑаÑзеÑÑ, кÑоме Safari, на даннÑй Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð¸Ð³Ð½Ð¾ÑиÑÑÑÑ ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ, но могÑÑ Ð½Ð°ÑаÑÑ Ð¸ÑполÑзоваÑÑ Ð² бÑдÑÑем. ÐÐ²Ð¸Ð´Ñ Ð±ÑдÑÑÐ¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ меÑода, безопаÑнÑм ÑеÑением ÑвлÑеÑÑÑ Ð¿ÐµÑедаÑа пÑÑÑой ÑÑÑоки. РкаÑеÑÑве алÑÑеÑнаÑÐ¸Ð²Ñ Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе пеÑедаÑÑ ÐºÐ¾ÑоÑкий заголовок Ð´Ð»Ñ ÑоÑÑоÑнии, в коÑоÑое пеÑÐµÑ Ð¾Ð´Ð¸Ñе.
- URL
-
ЧеÑез ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¿ÐµÑедаÑÑÑÑ URL-адÑÐµÑ Ð½Ð¾Ð²Ð¾Ð¹ новÑй запиÑи в иÑÑоÑии. ÐбÑаÑиÑе внимание, ÑÑо бÑаÑÐ·ÐµÑ Ð½Ðµ бÑÐ´ÐµÑ Ð¿ÑÑаÑÑÑÑ Ð·Ð°Ð³ÑÑзиÑÑ Ð´Ð°Ð½Ð½Ñй URL ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле вÑзова
pushState(), но Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð¿ÑÑаÑÑÑÑ ÑделаÑÑ ÑÑо позже, напÑимеÑ, поÑле Ñого, как полÑзоваÑÐµÐ»Ñ Ð¿ÐµÑезапÑÑÑÐ¸Ñ Ð±ÑаÑзеÑ. ÐовÑй URL-адÑÐµÑ Ð½Ðµ обÑзан бÑÑÑ Ð°Ð±ÑолÑÑнÑм; еÑли он оÑноÑиÑелÑнÑй, Ñо опÑеделÑеÑÑÑ Ð¾ÑноÑиÑелÑно ÑекÑÑего URL. ÐовÑй URL должен веÑÑи на ÑÐ¾Ñ Ð¶Ðµ домен, пÑоÑокол и поÑÑ, инаÑеpushState()вÑдаÑÑ Ð¸ÑклÑÑение. ÐаннÑй паÑамеÑÑ Ð½Ðµ ÑвлÑеÑÑÑ Ð¾Ð±ÑзаÑелÑнÑм; еÑли он не Ñказан, бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ URL ÑекÑÑего докÑменÑа.
ÐÑзов pushState() в некоÑоÑой ÑÑепени поÑ
ож на ÑÑÑÐ°Ð½Ð¾Ð²ÐºÑ window.location = "#foo", поÑколÑÐºÑ Ð¾Ð½Ð¸ оба Ñакже ÑоздаÑÑ Ð¸ акÑивиÑÑÑÑ ÐµÑÑ Ð¾Ð´Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð² иÑÑоÑии, ÑвÑзаннÑÑ Ñ ÑекÑÑим докÑменÑом.
Ðо Ñ pushState() еÑÑÑ Ð½ÐµÑколÑко пÑеимÑÑеÑÑв:
- ÐовÑй URL Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð»ÑбÑм в пÑеделаÑ
Ñого же домена, поÑÑа и пÑоÑокола, ÑÑо и ÑекÑÑий адÑеÑ. Тогда как наÑÑÑойка
window.locationоÑÑавлÑÐµÑ Ð²Ð°Ñ Ð½Ð° Ñом жеdocumentлиÑÑ Ð² Ñом ÑлÑÑае, еÑли Ð²Ñ Ð¼ÐµÐ½ÑеÑе ÑолÑко Ñ ÑÑ - ÐенÑÑÑ URL не обÑзаÑелÑно. Тогда как наÑÑÑойка
window.location = "#foo";ÑоздаÑÑ Ð½Ð¾Ð²ÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð² иÑÑоÑии, ÑолÑко еÑли ÑекÑÑий Ñ ÐµÑ Ð½Ðµ#foo - С новой запиÑÑÑ Ð² иÑÑоÑии можно ÑвÑзаÑÑ Ð»ÑбÑе даннÑе. Ð Ð¿Ð¾Ð´Ñ Ð¾Ð´Ðµ, оÑнованном на Ñ ÐµÑе, вÑе ÑооÑвеÑÑÑвÑÑÑие даннÑе нÑжно кодиÑоваÑÑ Ð² коÑоÑкÑÑ ÑÑÑокÑ
- ÐÑли заголовок
titleвпоÑледÑÑвии иÑполÑзÑеÑÑÑ Ð±ÑаÑзеÑами, ÑÑи даннÑе могÑÑ Ð±ÑÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ñ (незавиÑимо оÑ, Ñкажем, Ñ ÐµÑа).
ÐбÑаÑиÑе внимание, ÑÑо pushState() никогда не вÑзÑÐ²Ð°ÐµÑ ÑобÑÑие hashchange, даже еÑли новÑй URL оÑлиÑаеÑÑÑ Ð¾Ñ ÑÑаÑого ÑолÑко Ñ
еÑем.
Ð XUL-докÑменÑÐ°Ñ Ð¾Ð½ ÑоздаÑÑ ÑказаннÑй XUL-ÑлеменÑ
РдÑÑÐ³Ð¸Ñ Ð´Ð¾ÐºÑменÑÐ°Ñ Ð¾Ð½ ÑоздаÑÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ñ null namespace URI.
ÐеÑод replaceState()
history.replaceState() ÑабоÑÐ°ÐµÑ ÑоÑно Ñак же, как history.pushState(), за иÑклÑÑением Ñого, ÑÑо replaceState() изменÑÐµÑ ÑекÑÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð¸ÑÑоÑии вмеÑÑо ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð¹ запиÑи. ÐбÑаÑиÑе внимание, ÑÑо он не пÑедоÑвÑаÑÐ°ÐµÑ Ñоздание новой запиÑи в глобалÑной иÑÑоÑии бÑаÑзеÑа.
replaceState() оÑобенно полезен, когда Ð²Ñ Ñ
оÑиÑе обновиÑÑ Ð¾Ð±ÑÐµÐºÑ ÑоÑÑоÑÐ½Ð¸Ñ Ð¸Ð»Ð¸ URL ÑекÑÑей запиÑи в иÑÑоÑии в оÑÐ²ÐµÑ Ð½Ð° какое-Ñо дейÑÑвие полÑзоваÑелÑ.
ÐÑÐ¸Ð¼ÐµÑ Ð¼ÐµÑода replaceState()
ÐÑедположим, на ÑÑÑаниÑе http://mozilla.org/foo.html вÑполнÑеÑÑÑ ÑледÑÑÑий JavaScript-код:
let stateObj = { foo: "bar" };
history.pushState(stateObj, "page 2", "bar.html");
ÐбÑÑÑнение ÑÑÐ¸Ñ Ð´Ð²ÑÑ ÑÑÑок можно найÑи в пÑиведÑнном вÑÑе Ñазделе пÑÐ¸Ð¼ÐµÑ Ð¼ÐµÑода pushState().
Ðалее, пÑедположим, на ÑÑÑаниÑе http://mozilla.org/bar.html вÑполнÑеÑÑÑ JavaScript-код:
history.replaceState(stateObj, "page 3", "bar2.html");
ÐÑо пÑиведÑÑ Ðº ÑомÑ, ÑÑо в URL-ÑÑÑоке оÑобÑазиÑÑÑ Ð°Ð´ÑÐµÑ http://mozilla.org/bar2.html, но бÑаÑÐ·ÐµÑ Ð½Ðµ ÑÑÐ°Ð½ÐµÑ ÑÑÐ°Ð·Ñ Ð·Ð°Ð³ÑÑжаÑÑ bar2.html и даже не ÑÑÐ°Ð½ÐµÑ Ð¿ÑовеÑÑÑÑ Ð½Ð°Ð»Ð¸Ñие ÑÑой ÑÑÑаниÑÑ bar2.html.
ТепеÑÑ Ð¿Ñедположим, ÑÑо полÑзоваÑÐµÐ»Ñ Ð¿ÐµÑеÑ
Ð¾Ð´Ð¸Ñ Ð¿Ð¾ адÑеÑÑ http://www.microsoft.com, а заÑем Ð½Ð°Ð¶Ð¸Ð¼Ð°ÐµÑ Ð½Ð° ÐºÐ½Ð¾Ð¿ÐºÑ "Ðазад". Ð ÑÑом ÑлÑÑае в URL-ÑÑÑоке оÑобÑазиÑÑÑ http://mozilla.org/bar2.html. ÐÑли же полÑзоваÑÐµÐ»Ñ Ñнова нажмÑÑ Ð½Ð° ÐºÐ½Ð¾Ð¿ÐºÑ "Ðазад", в URL-ÑÑÑоке оÑобÑазиÑÑÑ http://mozilla.org/foo.html и полноÑÑÑÑ Ð¾Ð±Ð¾Ð¹Ð´ÑÑ bar.html.
СобÑÑие popstate
СобÑÑие popstate вÑзÑваеÑÑÑ Ð² окне каждÑй Ñаз, когда акÑÐ¸Ð²Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð² иÑÑоÑии менÑеÑÑÑ. ÐÑли запиÑÑ Ð² иÑÑоÑии, коÑоÑÐ°Ñ Ð°ÐºÑивиÑÑеÑÑÑ, бÑла Ñоздана Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð²Ñзова pushState или акÑивиÑована вÑзовом replaceState, ÑвойÑÑво state ÑобÑÑÐ¸Ñ popstate ÑодеÑÐ¶Ð¸Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñи в иÑÑоÑии обÑекÑа ÑобÑÑиÑ.
ÐÑимеÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ поÑмоÑÑеÑÑ Ð² Window.onpopstate.
ЧÑение ÑекÑÑего ÑоÑÑоÑниÑ
Ðогда ÑÑÑаниÑа загÑÑжаеÑÑÑ, она Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¾Ð±ÑÐµÐºÑ ÑобÑÑÐ¸Ñ Ñо знаÑением, оÑлиÑнÑм Ð¾Ñ "null". ÐÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоизойÑи, напÑимеÑ, еÑли ÑÑÑаниÑа ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¾Ð±ÑÐµÐºÑ ÑоÑÑоÑÐ½Ð¸Ñ (Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ pushState() или replaceState()) и заÑем полÑзоваÑÐµÐ»Ñ Ð¿ÐµÑезапÑÑÐºÐ°ÐµÑ Ð±ÑаÑзеÑ. Ðогда ÑÑÑаниÑа пеÑезагÑÑжаеÑÑÑ, она полÑÑÐ¸Ñ ÑобÑÑие onload, но не полÑÑÐ¸Ñ ÑобÑÑие popstate. Тем не менее, еÑли Ð²Ñ Ð¿ÑоÑиÑаеÑе ÑвойÑÑво history.state, полÑÑиÑе обÑÐµÐºÑ ÑоÑÑоÑниÑ, коÑоÑÑй полÑÑили, еÑли Ð±Ñ Ð¿ÑоизоÑло ÑобÑÑие popstate.
С помоÑÑÑ ÑвойÑÑва history.state можно пÑоÑиÑаÑÑ ÑоÑÑоÑние ÑекÑÑей запиÑи в иÑÑоÑии, не дожидаÑÑÑ ÑобÑÑÐ¸Ñ popstate, напÑимеÑ:
let currentState = history.state;