Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

157
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda