skip to Main Content

I just recently completed the basics of HTML, CSS, and Javascript. Now, I am trying to clone the home page of this website: https://www.startech.com.bd/. But I have run into a small problem. The webpage has an image slider, where the image changes every 5 seconds, and there are also three dots representing those three images, respectively.

Here is my code –

const imageResponsive = document.querySelectorAll('[data-image-responsive]');
const dot = document.querySelectorAll('[data-dot]');


let counter = 0;



function changeImage() {

  // First hide all images
  imageResponsive.forEach(img => img.style.display = 'none');

  // Show the current image based on the counter value
  imageResponsive[counter].style.display = 'block';

  // First hide all slider dots
  dot.forEach((span) => {
    span.style.background = '#fff';
    span.style.opacity = '0.5';
  });
  // Show the current slider dot based on the counter value
  dot[counter].style.background = '#ef4a23';
  dot[counter].style.opacity = '1';

  // Increment counter and reset if it exceeds the length of the image array
  counter = (counter + 1) % imageResponsive.length;


}



// Start the image change every 5 seconds
setInterval(changeImage, 5000);


// Initially display the first image and the slider dot
imageResponsive[0].style.display = 'block';
dot[0].style.background = '#ef4a23';
dot[0].style.opacity = '1';
.image-responsive-div {
  position: relative;
  width: 990px;
  height: 490px;
  padding: 0px 15px;
}

.image-responsive {
  width: 960px;
  height: 488px;
  position: absolute;
  box-shadow: 0 0.5px 4px 0 rgba(0, 0, 0, 0.3);
}

.slider-dot {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  text-align: center;
  padding: 10px 0;
}

.dot {
  display: inline-block;
  width: 30px;
  height: 8px;
  background: #fff;
  margin: 0 5px;
  opacity: .5;
  cursor: pointer;
}
<div class="image-responsive-div">
  <img class="image-responsive" data-image-responsive src="./resources/images/09-09-24a-v4-(antec-C8-offer-web-banner-design)-982x500.jpg" />
  <img class="image-responsive" data-image-responsive src="./resources/images/express-delivery-girl-receiving-parcel-home-banner-982x500.webp" />
  <img class="image-responsive" data-image-responsive src="./resources/images/queue-banner-home-service-982x500.png" />

  <div class="slider-dot">
    <span class="dot" data-dot></span>
    <span class="dot" data-dot></span>
    <span class="dot" data-dot></span>
  </div>
</div>

But the problem is with the slider. When the website loads, the first image and the first slider load up correctly, but then, when the second image comes, the slider still stays in first place. And when the third image comes, the slider moves to second place. Why is that?

I also tried asking Chatgpt but still did not understand what it said. Anyway, here is its answer: " The issue is happening because your counter is incremented after the images and dots are updated. This causes a delay in the slider dot movement. On the first run, the first image and first dot are shown correctly, but when the counter increments after updating the image for the second time, the dot update is out of sync with the image."

So, can someone explain why the slider and the image are out of sync during the 2nd run?

3

Answers


  1. New css class to show a dot when it is active:

    .dot.active {
        background: #ef4a23;
        opacity: 1;
    }
    

    Rewritten changeImage function and added startSlider function:

    let intervalID;
    
    function changeImage(index = counter) {
        // First hide all images
        imageResponsive.forEach(img => img.style.display = 'none');
    
        // Show the current image based on the counter value
        imageResponsive[index].style.display = 'block';
    
        // Update dots
        dot.forEach((span) => span.classList.remove('active'));
        dot[index].classList.add('active');
    
        // If no manual index, increment the counter
        if (index === counter) {
            counter = (counter + 1) % imageResponsive.length;
        }
    }
    
    // Start the image change every 5 seconds
    function startSlider() {
        intervalId = setInterval(() => changeImage(), 5000);
    }
    
    // Initially display the first image and the slider dot
    changeImage(0);
    
    // Start the automatic slider
    startSlider();
    

    Implementing these changes will fix the errors you were having, you could also look into having the images change when the buttons/dots are clicked on for added functionality, through something such as this:

    // Event listener for dots
    dot.forEach((span, index) => {
        span.addEventListener('click', () => {
            // Clear the auto slider when a dot is clicked
            clearInterval(intervalId);
            counter = index;  // Set the counter to the clicked dot index
            changeImage(index);  // Change image to the one corresponding to the clicked dot
            startSlider();  // Restart auto slider after manual change
        });
    });
    
    Login or Signup to reply.
  2. I believe your images and slider dots are in sync, the problem is just that you show all images at once before the timer is ran for the first time.

    When they all stack on top of each other the last one will be on top.

    I think what you are seeing is:

    • 3rd image + 1st dot
    • 2nd image + 2nd dot
    • 3rd image + 3rd dot
    • 1st image + 1st dot
    Login or Signup to reply.
  3. The problem is that initially the images don’t have display: none so the last one is visible on top of the others.

    Make them have display: none to start with by setting that in the style sheet.

    This snippet uses images we can see and the dog is the first one so you can check it always shows first

    const imageResponsive = document.querySelectorAll('[data-image-responsive]');
    const dot = document.querySelectorAll('[data-dot]');
    
    
    let counter = 0;
    
    
    
    function changeImage() {
    
      // First hide all images
      imageResponsive.forEach(img => img.style.display = 'none');
    
      // Show the current image based on the counter value
      imageResponsive[counter].style.display = 'block';
    
      // First hide all slider dots
      dot.forEach((span) => {
        span.style.background = '#fff';
        span.style.opacity = '0.5';
      });
      // Show the current slider dot based on the counter value
      dot[counter].style.background = '#ef4a23';
      dot[counter].style.opacity = '1';
    
      // Increment counter and reset if it exceeds the length of the image array
      counter = (counter + 1) % imageResponsive.length;
    
    
    }
    
    
    
    // Start the image change every 5 seconds
    setInterval(changeImage, 5000);
    
    
    // Initially display the first image and the slider dot
    imageResponsive[0].style.display = 'block';
    dot[0].style.background = '#ef4a23';
    dot[0].style.opacity = '1';
    .image-responsive-div {
      position: relative;
      width: 990px;
      height: 490px;
      padding: 0px 15px;
    }
    
    .image-responsive {
      width: 960px;
      height: 488px;
      position: absolute;
      box-shadow: 0 0.5px 4px 0 rgba(0, 0, 0, 0.3);
      display: none;
    }
    
    .slider-dot {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      text-align: center;
      padding: 10px 0;
    }
    
    .dot {
      display: inline-block;
      width: 30px;
      height: 8px;
      background: #fff;
      margin: 0 5px;
      opacity: .5;
      cursor: pointer;
    }
    <div class="image-responsive-div">
      <img class="image-responsive" data-image-responsive src="https://picsum.photos/id/237/982/500" />
      <img class="image-responsive" data-image-responsive src="https://picsum.photos/id/1015/982/500" />
      <img class="image-responsive" data-image-responsive src="https://picsum.photos/id/1016/982/500" />
    
      <div class=" slider-dot ">
        <span class="dot " data-dot></span>
        <span class="dot " data-dot></span>
        <span class="dot " data-dot></span>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search