3

I want a div to flash in case a user clicks on it. Is there a solution without manually running setTimeout?

Solution with setTimeout:

app.html

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<style>
div { transition: background-color 1s; }
div.flashing { background-color: green; transition: none; }
</style>

<div id="app" :class="{'flashing':flashing}" v-on:click="flash">flash when clicked</div>

app.js

const data = { flashing: false }

new Vue({
  el: '#app',
  data,
  methods: { flash }
})

function flash() {
  data.flashing = true;
  setTimeout(() => data.flashing = false, 100);
}

Js Fiddle: https://jsfiddle.net/ang3ukg2/

3
  • When/where do you want to set the time? Commented Feb 6, 2018 at 23:50
  • Why not use css :active? Commented Feb 6, 2018 at 23:51
  • Maybe you can use the mousedown and mouseup events instead of the click event and then benifit from the css transitions? Commented May 26, 2020 at 14:29

2 Answers 2

16

Similar to Christopher's answer, but in a way that is more idiomattic to Vue. This uses CSS animation applied via bound classes and the animationend event.

var demo = new Vue({
  el: '#demo',
  data: {
    animated: false
  },
  methods: {
    animate() {
      this.animated = true
    }
  }
})
<link href="https://unpkg.com/[email protected]/animate.min.css" rel="stylesheet" />
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="demo">
  <h1 :class="{'bounce animated': animated}" @animationend="animated = false">
    Animate Test
  </h1>
  <button @click="animate">
    Animate
  </button>
</div>

All credit to Robert Kirsz who proposed the solution in a comment to another question.

Sign up to request clarification or add additional context in comments.

1 Comment

This should be the accepted answer, as it solves the problem of removing the class at the end of animation.
0

An alternative is to use CSS animations and hook into the animationend event:

app.html

<div id="app" v-on:click="toggleClass('app', 'flashing')">flash when clicked</div>

app.css

.flashing {
  animation: flash .5s;
}

@keyframes flash {
  0% {
    background-color: none;
  }
  50% {
    background-color: green;
  }
  100% {
    background-color: none;
  }
}

app.js

new Vue({
  el: '#app',

  methods: {
    toggleClass (id, className) {
        const el = document.getElementById(id)
        el.classList.toggle(className)
    }
  },

  mounted () {
    document.getElementById('app').addEventListener('animationend', e => {
        this.toggleClass(e.target.id, 'flashing')
    })
  }
})

Working example: https://jsfiddle.net/Powercube/ang3ukg2/5/

This would allow you to reuse the toggleClass method for other classes without muddying the application with arbitrary class data and timeouts.

You can find more information about animation events at the MDN.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.