Managing scripts & styles
On some productions, some scripts & styles are only loaded by page ( for example Wordpress with Woocommerce, ... ). Highway replacing only the data-router-view
, this behavior is not managed natively by Highway.
Here are two functions that will allow you to make sure that your new page will have all necessary scripts & styles ( as if it was a real page load ). Those two functions should be called in Highway's Core NAVIGATE_END
event, do not forget to pass the to
value
Managing scripts function:
You can prevent the reloading of some scripts by adding the data-no-reload
attribute to the desired script
manageScripts(to) {
// Your main JS file, used to prepend other scripts
const main = document.querySelector('#main-script');
const a = [...to.page.querySelectorAll('script:not([data-no-reload])')];
const b = [...document.querySelectorAll('script:not([data-no-reload])')];
// Compare Scripts
for (let i = 0; i < b.length; i++) {
const c = b[i];
for (let j = 0; j < a.length; j++) {
const d = a[j];
if (c.outerHTML === d.outerHTML) {
// Create Shadow Script
const script = document.createElement(c.tagName);
// Loop Over Attributes
for (let k = 0; k < c.attributes.length; k++) {
// Get Attribute
const attr = c.attributes[k];
// Set Attribute
script.setAttribute(attr.nodeName, attr.nodeValue);
}
// Inline Script
if (c.innerHTML) {
script.innerHTML = c.innerHTML;
}
// Replace
c.parentNode.replaceChild(script, c);
// Clean Arrays
b.splice(i, 1);
a.splice(j, 1);
// Exit Loop
break;
}
}
}
// Remove Useless
for (const script of b) {
// Remove
script.parentNode.removeChild(script);
}
// Add Scripts
for (const script of a) {
const loc = script.parentNode.tagName;
if (loc === 'HEAD') {
document.head.appendChild(script);
}
if (loc === 'BODY') {
document.body.insertBefore(script, main);
}
}
}
Managing styles function:
You can prevent the reloading of some styles by adding the data-no-reload
attribute to the desired styles
manageStyles(to) {
// Your main css file, used to prepend other styles
const main = document.querySelector('#main-style');
const a = [...to.page.querySelectorAll('style:not([data-no-reload]), link:not([data-no-reload])')];
const b = [...document.querySelectorAll('style:not([data-no-reload]), link:not([data-no-reload])')];
// Compare Styles
for (let i = 0; i < b.length; i++) {
const c = b[i];
for (let j = 0; j < a.length; j++) {
const d = a[j];
if (c.outerHTML === d.outerHTML) {
// Create Shadow Style
const style = document.createElement(c.tagName);
// Loop Over Attributes
for (let k = 0; k < c.attributes.length; k++) {
// Get Attribute
const attr = c.attributes[k];
// Set Attribute
style.setAttribute(attr.nodeName, attr.nodeValue);
}
// Style Tag
if (c.tagName === 'STYLE') {
if (c.innerHTML) {
style.innerHTML = c.innerHTML;
}
}
// Replace
c.parentNode.replaceChild(style, c);
// Clean Arrays
b.splice(i, 1);
a.splice(j, 1);
// Exit Loop
break;
}
}
}
// Remove Useless
for (const style of b) {
// Remove
style.parentNode.removeChild(style);
}
// Add Styles
for (const style of a) {
const loc = style.parentNode.tagName;
if (loc === 'HEAD') {
document.head.insertBefore(style, main);
}
if (loc === 'BODY') {
document.body.appendChild(style);
}
}
}