The pushState()
and replaceState()
functions are responsible for updating the browser history when a new URL is requested; pushState()
adds a new entry to the browser history for the URL while replaceState()
replaces the current entry. In their native form, pushState()
and replaceState()
only modify the browser history, they do not trigger a page load for the new URL. Commerce Store Accelerator extends pushState()
and replaceState()
with an additional parameter, triggerPushStateEvent
. When triggerPushStateEvent
is true, one of the following events is triggered:
The
pushstate
event is triggered for thepushState()
function.The
replacestate
event is triggered for thereplaceState()
function.
Both of these events trigger a subsequent changestate
event. In the router.js
script, an instance of the Crossroads router is created and integrated with the changestate
event, allowing the router to be notified when a changestate
event occurs.
// Create a router instance var router = crossroads.create(); window.addEventListener('changestate', function (e) { // Notify the router of the URL change router.parse(e.detail.URL);
After the router is notified, you can use the Crossroads API to match the pattern of the current URL to code you would like to execute, for example:
router.addRoute('/cart', function () { alert('Cart page loaded'); });
Note that Crossroads is only the mechanism for URL pattern matching and does not itself detect URL changes in the browser. For that, Crossroads must be integrated with the changestate
event, as shown above.
In order to invoke the extended versions of pushState()
and replaceState()
, Commerce Store Accelerator must hijack the request first. Specifically, the history.js
script listens for two types of events:
Click events for anchor tags:
$(document).on('click', 'a:not([data-bypass],[target])', function (event) { });
Note: Anchor tags with the attribute
data-bypass
ortarget
are not hijacked and behave as normal links, loading content from the URL. The purpose of thedata-bypass
attribute is to give application developers a simple and explicit mechanism to bypass the router. Thetarget
attribute normally causes the URL to be open in a new tab or window, so it does not make sense to hijack these links because the current window is not reloaded anyway.Submit events for HTTP GET forms:
$(document).on('submit', 'form[method="GET"]', function (e) { });
Note: POST forms are never hijacked. POST actions effect state change and re-running POST actions, for example, purchasing an order, may cause unexpected or undesirable side effects.
When it detects one of these two event types, history.js
hijacks the request by suppressing the default page loading behavior:
e.preventDefault();
Then history.js
calls the extended version of either pushState()
or replaceState()
. If the new URL is the same as the current URL, replaceState()
is called, otherwise pushState()
is called. Using replaceState()
avoids the scenario where a user clicks the same link multiple times. Instead of creating multiple, identical entries in the history, a single entry for the link is created.
if (URL === window.location.href) { window.history.replaceState(null, null, URL, true); } else { window.history.pushState(null, null, URL, true); }