Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

153
Views
Cleanest way to toggle class in list through setInterval

I would like to toggle an 'active' class in a list of elements:

<div ref="gallery" class="slider">
  <div class="slide active">
  <div class="slide">
  <div class="slide">
</div>

Using Vue and Vanilla JS

Slider() {
  const slider = document.querySelectorAll('.slider')
  for (const slide of slider) {
    setInterval(function () {
      const current = slide.querySelector('.active')
      current.classList.remove('active')
      const next = current.nextElementSibling || slide.firstElementChild
      next.classList.add('active')
    }, 5000)
  }
}

While the above code does work, I feel it is not as clean as it could be.

Also, and mainly, if I target the slider using a Vue ref like:

const slider = this.$refs.gallery

it stops working


tony19 answer led me to reduce the code even further using Nuxt:

export default {
  data() {
    return {
      activeIndex: 0,
      slides: [
        { id: 1, text: 'Slide 1' },
        { id: 2, text: 'Slide 2' },              
        { id: 3, text: 'Slide 3' },
      ]
    }
  },
  mounted() {
    this.Slider()
  },
  methods: {
    Slider() {
      setInterval(() => {
        this.activeIndex = (this.activeIndex + 1) % this.slides.length
      }, 3000)
    }
  }   
}

<template>
  <div class="slider">
    <div v-for="(slide, index) in slides"
      :key="slide.id"
      :class="['slide', { active: index === activeIndex }]">
      {{ slide.text }}
    </div>
  </div>
</template>
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

You can use a class binding that sets class to active based on the active index:

  1. Declare an activeIndex property to hold the active index.

  2. In the mounted hook, use setInterval() with a callback that increments activeIndex. Track the timer ID from setInterval() so that we can stop the timer later.

  3. In the unmounted hook, stop the interval timer with clearInterval() on the timer ID.

  4. Use the object syntax for class bindings to bind an active class only when the activeIndex matches the slide's index from v-for.

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

let timerId = -1
1️⃣
const activeIndex = ref(0)
const slides = ref([
  { id: 1, text: 'Slide 1' },
  { id: 2, text: 'Slide 2' },
  { id: 3, text: 'Slide 3' },
])

2️⃣
onMounted(() => {
  timerId = setInterval(() => {
    activeIndex.value = (activeIndex.value + 1) % slides.value.length
  }, 3000)
})
3️⃣
onUnmounted(() => {
  clearInterval(timerId)
})
</script>

<template>
  <div ref="gallery" class="slider">
    <div v-for="(slide, index) in slides"
      :key="slide.id"
      class="slide"
      4️⃣
      :class="{ active: index === activeIndex }">
      {{ slide.text }}
    </div>
  </div>
</template>

demo

about 4 years ago · Juan Pablo Isaza Report

0

I made this demo in vue.js format as per your request. Please have a look and see if this is what you actually want to achieve.

Demo :

new Vue({
  el: '#app',
  data: {
    slideData: [{
        name: 'Slide 1',
      isActive: true
    }, {
        name: 'Slide 2',
      isActive: false    
    }, {
        name: 'Slide 3',
      isActive: false    
    }]
  },
  mounted() {
    this.slideData.forEach((obj) => {
      setInterval(() => {
        obj.isActive = !obj.isActive;
      }, 3000);
    });
  }
})
.active {
  color: white;
  background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(slider, index) in slideData" class="slide" :class="{ active: slider.isActive }">
  {{ slider.name}}
</div>
</div>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!