skip to Main Content

I’m not sure how to make this work

let progressBar = document.querySelector(".circular-progress");
let valueContainer = document.querySelector(".value-container");

let progressValue = 0;
let progressEndValue = 65;
let speed = 50;

let progress = setInterval(() => {
    progressValue++;
    valueContainer.textContent = `${progressValue}%`;
    progressBar.style.background = `conic-gradient(
        #FBDA9D ${progressValue * 3.6}deg,
        #683279 ${progressValue * 3.6}deg
    )`;
    if (progressValue == progressEndValue) {
        clearInterval(progress);
    }

}, speed);

Updated to be a bit cleaner – this code works on page load, I would like to know how to activate it when it comes to view.

2

Answers


  1. I think it says addEventListener requires a js method, not class selector. You can learn more on MDN Web Docs or w3Schools

    The usage of addEventListener is this:

    document.addEventListener("scroll", function(){
      // Code
    });
    

    I don’t understand exactly what you are trying to do by writing

    document.addEventListener('scroll', ".value-container");
    

    but you should do it with this syntax that written in MDN Web Docs:

    addEventListener(type, listener)             // or
    addEventListener(type, listener, options)    // or
    addEventListener(type, listener, useCapture)
    

    (And listener means a function)

    Login or Signup to reply.
  2. You could use the Intersection Observer API. This is a build in Browser API which can determine if a element is in the viewport / visible.

    In your case your code could look like this:

       let options = {
          root: document.querySelector("body"),
          rootMargin: "0px",
          threshold: 1.0,
       };
    
       let interval;
    
        // this function gets called everytime the intersection status changes - so when it becomes visible and becomes hidden
        const observerCallback = (entries) => {
          // you only have one item so you can directy use index 0
          if (entries[0].isIntersecting) {
            interval = setInterval(progress, speed)
          }
          else {
           // OPTIONAL: Stop the animation and reset it if it leaves the viewport
           clearInterval(interval);
           progressValue = 0;
        }
    
        let observer = new IntersectionObserver(observerCallback, options);
    
        // this tells the observer to observe your element
        observer.observe(document.querySelector(".circular-progress"));
    

    Also you’ll need to update your progress function. The way you define it, the interval starts as soon as the script gets executed. As soon as setInterval() gets called the interval starts.

    const progress = () => {
        progressValue++;
        valueContainer.textContent = `${progressValue}%`;
        progressBar.style.background = `conic-gradient(
            #FBDA9D ${progressValue * 3.6}deg,
            #683279 ${progressValue * 3.6}deg
        )`;
        if (progressValue == progressEndValue) {
            clearInterval(interval);
        }
    
    }
    

    Just call it in the observer callback function as seen above.

    Also this line wont work:

    element.classList.add(progress);
    

    progress will get a numeric id assigned by the setInterval function, so appending the id to the elements classlist will not work as intented, because it is not a valid class. You are using the element provided by document.querySelector, so you are already applying the styles to the object in the DOM. (also element is not defined – at least in the snippet you provided)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search