Set Up the Stream Progress Bar
<div class="progress-bar-container"> <div class="progress-bar"></div> </div>
Implementing JavaScript Routes :
document.addEventListener("DOMContentLoaded", function () { const progressBar = document.getElementById("progress-bar"); // Update the progress bar width based on the loading percentage function updateProgressBar(percentage) { progressBar.style.width = `${percentage}%`; progressBar.classList.add("filled"); // hide progress bar when content is loaded if (percentage == 100) { setTimeout(() => { progressBar.classList.remove("filled"); progressBar.style.width = 0; }, 300); } } // Fetch content based on the URL and update the page function fetchContent(url) { updateProgressBar(0); // Reset progress bar console.log(url); fetch(url, { headers: { "Content-Type": "text/html; charset=utf-8", }, mode: "cors", }) .then((response) => { const reader = response.body.getReader(); const decoder = new TextDecoder("utf-8"); const total = +response.headers.get("Content-Length"); let loaded = 0; let html = ""; function read() { reader.read().then(({ done, value }) => { if (done) { const parser = new DOMParser(); const doc = parser.parseFromString(html, "text/html"); // Extract the specific HTML element and their child's from the parsed document const primary = doc.querySelector("#primary"); // take content element from current page const appContainer = document.getElementById("content"); // Then, Remove all child elements while (appContainer.firstChild) { appContainer.removeChild(appContainer.firstChild); } // Append a new element appContainer.appendChild(primary); updateProgressBar(100); // Set progress bar to 100% when content is loaded return; } loaded += value.length; updateProgressBar((loaded / total) * 100); const chunk = decoder.decode(value, { stream: true }); html += chunk; // Process the content here if needed // somthing like pelase wait or spinner.. read(); // Continue reading the stream }); } read(); }) .catch((error) => { console.error(error); updateProgressBar(0); // Reset progress bar in case of errors }); } // Handle link clicks function handleLinkClick(event) { const target = event.target; // Check if the clicked element or its parent is an anchor element const anchor = target.closest("a"); if (anchor) { event.preventDefault(); // Get the href attribute of the anchor element const targetUrl = anchor.getAttribute("href"); // Update the URL and push a new history state history.pushState(null, "", targetUrl); // Fetch and load the content for the clicked link fetchContent(targetUrl); } } // Attach click event listeners to all links const allLinks = document.querySelectorAll("a"); allLinks.forEach((link) => { link.addEventListener("click", handleLinkClick); }); // Handle the popstate event to update the page when the user navigates back/forward window.addEventListener("popstate", () => { fetchContent(window.location.href); }); });
In the above code, we first attach an event listener to the DOMContentLoaded event to ensure our JavaScript code runs when the page has finished loading.
The handleLinkClick function is responsible for intercepting link clicks, preventing the default behavior, starting the progress bar animation, and fetching the content for the clicked link using the fetchContent function.
The fetchContent function sends a GET request to the target URL, retrieves the response as text, stops the progress bar animation, and updates the content container with the fetched HTML.
Make sure to have a CSS file linked to your HTML, where you can define the styles for the progress bar animation. Here's a basic CSS example for the progress bar:
.progress-bar-container { width: 100%; height: 2px; background-color: transparent; position: absolute; top: 0; display: block; } .progress-bar { width: 0; height: 100%; background-color: #f00; position: relative; transition: width 0.3s ease-in-out; opacity: 0; } .progress-bar.filled { opacity: 1; } /* Optional: Add animation to the progress bar */ @keyframes progress-animation { 0% { width: 0; } 100% { width: 100%; } }
Feel free to customize the CSS styles to match your website's design.
function(data)should be something likefunction(data){ $('.myDiv').html(data)}$("a").click(function(){ return false;...