Animating a Vue component using mouseover and mouseout

marcellorvalle picture marcellorvalle · Nov 27, 2018 · Viewed 7.2k times · Source

I am trying to create a Vue component that bounces when the mouse cursor hover over it. I am using the animate.css library and changing the component class with @mouseover then resetting it on @mouseout.

It is almost ok. The only issue occurs when the user stops the cursor near the border. Due to the animation behavior, the mouseover/mouseout events will be called repeatedly, causing the component to flick. I could minimize it using a timeout before resetting the class but the behavior is still uncertain sometimes.

Is there any elegant way (or Vue way) to solve it?

Here is my code:

Html:

<head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
</head>
<body>
  <div id="app">
  <h1>Hover the mouse near the border</h1>
  <hr>
    <button :class="classes"
      @mouseover="hoverOver"
      @mouseout="hoverOut"
    >
      IMMEDIATE
    </button>
    <br><br><br>
    <button :class="classes"
      @mouseover="hoverOver"
      @mouseout="hoverOutTimeout"
    >
      WAIT JUST A BIT
    </button>
  </div>  
</body>

Javascript:

new Vue({
  el: "#app",
  data: {
    classes: []
  },
  methods: {
    hoverOver: function() {
        console.log('over');
        this.classes = ['animated', 'bounceIn']
    },
    hoverOut: function() {
        console.log('out');
        this.classes = []
    },
    hoverOutTimeout: function() {
        setTimeout(() => { 
        console.log('out');
            this.classes = []
      }, 1000);
    },
  }
})

https://jsfiddle.net/marcellorvalle/eywraw8t/477611/

Answer

Jim B. picture Jim B. · Nov 27, 2018

Neat. Looks like as the button changes size during the animation, the mouse goes in and out of hover state because the edge is moving.

I added a div around each button, and attached the hover triggers to the divs instead of the buttons:

<body>
    <div id="app">
        <h1>Hover the mouse near the border</h1>
        <hr>
        <div @mouseover="hoverOver" @mouseout="hoverOut">
            <button :class="classes">IMMEDIATE</button>
        </div>
        <br><br><br>
        <div @mouseover="hoverOver" @mouseout="hoverOutTimeout">
            <button :class="classes">WAIT JUST A BIT
        </button>
        </div>
    </div>
</body>

https://jsfiddle.net/jmbldwn/kbswLpto/5/