What could be more useful than the ability to swap chunks of html on the page and have new content available in a split second? This is easily done by using the js 'fetch' and 'innerHTML =' to set the contents of a div, whether plain text or whatever.
I put it to use in building my image galleries at my other website, so that I could easily swap out the image sets on the same page, which is far more user-friendly than sending people to new pages.
Fetching html
All you have to do is tell the javascript fn which div to dump the html into, such as a div with class name "fetch" or "load-html".
The js to do this looks something like this, which runs a fn 'fetchInitial' on page load..
What it does..
const titlesUrl sets the URL of the file to fetch
const response sets the fetch process
const htmlContent declares it as plain text
const fetchdiv sets the load div
fetchdiv.innerHTML = overwrites the div content with 'htmlContent'
window.scrollTo sets the page to return to top, in case the fetched html is longer that the screen and drags the view down
The variables ${target-id} and ${imageDir} are set by an argument to the 'onload' fn and a parameter in the script tag placed on the gallery page, like this..
View code
The top gallery page structure is as follows..
View code
Note! You need to drop a dummy piece of html in the 'Fetching DIV' area containing the div classes that the js will look for as soon as the page loads - without which errors will spring up and spoil the show. The dummy html will be wiped out immediately by the script. Include any classes that the js needs to see on the page (even before they are loaded).
The initial html file to fetch after the page loads (which is called by the script tag) will be the gallery sets, a row or rows of thumbs, each of which lead to an individual lightbox with its own set of thumbnails and slides. Each lightbox is a html file to be fetched into the fetching DIV, as we'll see.
So the initial html file will look like..
View code
The 'onclick' fn on each line calls the 'fetchHtml' fn with a target id as an argument, which is basically the file name, that will be sourced as a parameter by the fetchHtml function.
In my CSS, the 'gallery-row' div class is set to a flexbox container, so that the thumbs can flow to the next line on smaller screens
The 'gallery-col' div class contains the thumbs with a description.
The 'launcher' div class is set to brighten (turn opacity 1 from 0.8) and give a border to thumbs when hovered.
The tabindex="0" attribute at the end of the lines enables selecting the thumbs with the Tab key.
Basic fetches
Cross-fading fetches
How does it work then, cross-fading one piece of html with another?
First I'll show you the page structure..
View code
The two divs with the id's 'running' and 'fetch' sit exactly one on top of the other - and first of all I did this with 'position: absolute' , but it can be done with 'display: grid' on the container and the child divs both in col 1 and row 1, then no worries with setting the container height (absolute divs don't affect parent div height and they change all the time).
The css looks like...
View code
One div is shown (css display opacity 1) while the other not shown (class name 'fade-out' with display opacity 0) .
When the function is called, 'running' is given class name 'fade-out', while 'fetch' which already has the class name 'fade-out' has the class name removed, to make it fade-in.
Following a 1sec pause, the faded out 'running' div is wiped of its content, its name stored in a temporary variable, while the now visible 'fetch' div is given the id 'running', and finally the temporary var name is given the id 'fetch' (the temp var is necessary so that the we don't make two divs with the id 'running').
And the js function looks like this...
The 1st 'setTimeout' fn ensures that the last part is held for 1000ms before it follows through, to allow the cross-fade to complete first and not interrupt it abrubtly which is bad visually. Clever?
By finding the script tag I can extract a variable in it to fill in the 'fetchDir' variable, or the base dir of images. This can therefore be set by the script tag for any gallery and we don't need to hard code it into the js and need to edit the js file for each gallery.
Actually, you can send multiple arguments in the fn call, like fetchHtml('target', '/image/path'), but it might get typos.
Don't need to use running.innerHTML = "" as fetching html to the div clears any existing content. (this actually causes blank pages when clicking too fast on a fetch button).
The 'window,scrollTo' fn is set to scroll up if a thumbs list has been browsed and the top buttons/thumbs are off the page. The 270 value allows for my title to come in view.
The 2nd 'setTimeout' fn is used to seset focus to a specific element in the new ntml, so that hitting Tab key will curse through the buttons/thumbs.
I initially used a 'setHeight' fn to push the footer down, as the element was 'display: absolute' and the container didn't expand with it, but now I use grid on the container which auto grows with its content.
This was done out by finding the height of the new html content in the 'running' id div, and applying that height to the parend div ('fetch-containes'). The fn is called when a page height resize is detected, which means it will also run if someone resizes the page.
And the js snippet I used for this.. notet hat it won't w'rk when the thumbs element keeps changing height - using a resize slider.
And that's just about all there is to it!
One more thing, instead of fetching a file with the lightbox html, I need to fetch a page with the jekyll includes such as dir name, no. of lines to produce (no. of images) etc.
I also include previous and next buttons with onClick targets to the pages of adjacent thumnail sets, and a back button, to fetch the top page again.)