Tips For Developers Using This Project
Thank you @MackinnonBuck for providing this sample project - I integrated it into Oqtane (https://github.com/oqtane/oqtane.framework) so that we can provide developers with a much easier method for integrating Bootstrap templates.
A few notes for other developers who may be interested in utilizing this BlazorPageScript component:
- It relies on "JavaScript Initializers" (https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/startup?view=aspnetcore-8.0) which allow you to execute logic before and after a Blazor app loads.
- The JavaScript Initializer is named wwwroot/BlazorPageScript.lib.module.js - it registers a custom HTML element called "page-script" which accepts a single parameter of "src".
- The most critical event when running on Static Blazor using Enhanced Navigation is the "onUpdate" event. This event is called on every page transition and basically replaces the traditional role of the JavaScript "onload" event.
- The onUpdate event is not just called once - it is called multiple times. Originally I thought it would be a good idea to create a function so that it only executes my custom script once (ie. by comparing the url with the previous url) however this turned out to be a bad idea as the onUpdate event can be triggered prior to all components on your page being fully rendered - which means that if your script relies on the existence of a specific element - that element may not exist on the page yet. So its best to process every onUpdate event.
- When you create your script you usually only need to implement the onUpdate event as it handles new page loads as well as page transitions.
function myPageInitializer() {
// implementation
}
export function onUpdate() {
myPageInitializer();
}
- If the script you want to execute contains window.addEventListener('load', xxx) methods you will want to remove them as the "load" event is never called in page transitions.
window.addEventListener('load', () => {
if (window.location.hash) {
if (select(window.location.hash)) {
scrollto(window.location.hash)
}
}
});
becomes
if (window.location.hash) {
if (select(window.location.hash)) {
scrollto(window.location.hash)
}
}
You had any luck w/ AOS?
Yes I was able to get AOS working as part of a BootstrapMade template
Any tips or an example? I was struggling with initiating actually. It is trying to initiate before script is loaded in page-script (my thought).
TBH, I'm not seasoned in js at all, so it is hard to me figuring it out.
Thanks in advance!
@obrana-boranija I should be able to post a functional example of AOS within the next week... however the example will be based on Oqtane (https://github.com/oqtane/oqtane.framework) so the implementation will be slightly different than the samples which Mackinnon provided in this repo.
@sbwalker Thanks a lot for that!
In the meantime, do you think I'm on the right path here?
const aosScriptInfo = {
referenceCount: 0,
module: null
};
async function initializeAosModule() {
if (!aosScriptInfo.module) {
// Load AOS CSS
if (!document.querySelector('link[href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css"]')) {
const link = document.createElement('link');
link.href = 'https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css';
link.rel = 'stylesheet';
document.head.appendChild(link);
}
// Dynamically import AOS JS
const module = await import('https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js');
aosScriptInfo.module = module;
module.default.init({
duration: 1000, // AOS initialization options if needed
easing: 'ease-in-out',
once: false,
mirror: false
});
}
aosScriptInfo.module.default.refreshHard();
}
function onEnhancedLoad() {
if (aosScriptInfo.referenceCount <= 0) {
aosScriptInfo.module?.default?.refreshHard();
}
}
export function afterWebStarted(blazor) {
customElements.define('aos-script', class extends HTMLElement {
connectedCallback() {
aosScriptInfo.referenceCount++;
initializeAosModule();
}
disconnectedCallback() {
aosScriptInfo.referenceCount--;
}
});
blazor.addEventListener('enhancedload', onEnhancedLoad);
}
export function onUpdate() {
// Ensure AOS is refreshed on every update/navigation
initializeAosModule();
}
It is working, but I have concerns about optimization and memory leaks. As I already said, I am not proficient in JS, so it's better to ask someone seasoned. :)
@obrana-boranija I published a repo with a functional example of how blazor-page-script is used in Oqtane:
https://github.com/oqtane/Oqtane.Theme.Arsha
As I mentioned above, how you integrate blazor-page-script will vary based upon the requirements of your own application... but the script you posted above looks fine to me at first glance.
Thank you @sbwalker for posting this.
I was having trouble having bootstrap event (hovers, clicks) working with the theme I'm working with. Turns out the author had bundled bootstrap with the theme specific javascript, and when using enhanced navigation with the pagescript component, all bootstrap event handlers stopped working on every 2nd update.
I yanked bootstrap from there after looking how you're doing it in the octane theme, and loading it normally with my other vendor libraries.
Only took me 8 hours to figure out what was going on and prevented me from deciding on using JSInterop lol :)