DEV Community

farid teymouri
farid teymouri

Posted on • Updated on

Creating JavaScript Routes for WordPress Website with Stream CSS Progress Bar

Image description

In this article, we will learn how to create JavaScript routes for a WordPress website, allowing smooth client-side navigation, and implement a stream CSS progress bar to enhance the user experience. We'll be using native JavaScript without any frameworks or libraries. By the end of this tutorial, you will have a solid understanding of how to build JavaScript routes and implement a stream CSS progress bar in your WordPress website.

Prerequisites

To follow along with this article, you should have a basic understanding of HTML, CSS, and JavaScript. Additionally, familiarity with WordPress and its templating system will be beneficial.

Getting Started

Before we dive into the code, make sure you have a WordPress website up and running. Create a new directory in your theme directory and name it js. Inside the js directory, create a new file called main.js. This will be our main JavaScript file where we'll implement the JavaScript routes and stream CSS progress bar.

Open the functions.php file of your WordPress theme and enqueue the main.js file. Add the following code to your functions.php file:

function enqueue_custom_scripts() {
    wp_enqueue_script( 'custom-scripts', get_template_directory_uri() . '/js/main.js', array(), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'enqueue_custom_scripts' );
Enter fullscreen mode Exit fullscreen mode

This code ensures that the main.js file is loaded on the frontend of your WordPress website.

Set Up the Stream Progress Bar

  1. Open your WordPress theme's header.php file.
  2. Add a stream progress bar element to the HTML structure. For example:
<div class="progress-bar-container">
  <div class="progress-bar"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

Implementing JavaScript Routes

Now, let's start implementing JavaScript routes for our WordPress website. Open the main.js file and add the following code:

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");
              if (primary) {
                // Then, Remove all child elements
                while (appContainer.firstChild) {
                  appContainer.removeChild(appContainer.firstChild);
                }
                // Append a new element
                appContainer.appendChild(primary);
              } else {
                //  open it regular
                return window.open(url, "_self");
              }
              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");
      try {
        // Update the URL and push a new history state
        history.pushState(null, "", targetUrl);
      } catch (error) {
        return window.open(targetUrl, "_self");
      }
      // 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);
  });
});

Enter fullscreen mode Exit fullscreen mode

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%;
  }
}
Enter fullscreen mode Exit fullscreen mode

With this setup, whenever a link is clicked on your WordPress website, the JavaScript code will intercept the click event, initiate the progress bar animation, fetch the content for the clicked link, and update the content container seamlessly.

Feel free to customize the CSS styles to match your website's design.

That's it! You have successfully implemented JavaScript routes with a stream CSS progress bar for your WordPress website. Users will now experience smooth and visually appealing navigation between different pages.

Top comments (0)