VueJs keydown event stacking up

I'm building a <textarea> field that starts fading out once the user types on it v-on:keydown, but if he keeps on typing the fades resets keeping the opacity: 1.

However, the behaviour is different than expected. The more the users type the faster the fade starts happening, ignoring the setTimeout defined, and over time getting back to normal (eg.: if there's one letter on the <textarea> the fade behaves accordingly; if there are two letters it runs the fade out function twice, first time with double speed and second time on a normal speed; three letters, 3 times, 3 times as fast once...).

This is what I have so far:

<textarea placeholder="Start typying your text here..." v-model="text" v-on:keydown="startFade" ref="textArea" style="opacity: 1"> </textarea>

Methods:

methods: {
  fader(element) {

    if (element.style.opacity == 0) {
      this.text = ''
      element.style.opacity = 1
      console.log(element.style.opacity)
    } else {
      element.style.opacity = element.style.opacity - 0.1
      setTimeout(() => {
        console.log(element.style.opacity)
        this.fader(element)
      }, 1000);
    }
  },
  startFade() {
    let element = this.$refs.textArea;
    element.style.opacity = 1;
    setTimeout(() => {
      this.fader(element)
    }, 1000);
  }
}

How do I stop this events to pile up and just run one time?

I tried adding a clearTimeout() to reset the function, but it didn't work.

Upvotes: 0

Views: 1184

Answers (2)

Roy J
Roy J

Reputation: 43899

To use clearTimeout effectively, you would have had to pass it the value returned from your previous setTimeout.

Your approach is too DOM-oriented, anyway. You should be adjusting a variable that appears in a v-bind:style. The fader should be an interval that runs continuously, and the key event resets the variable.

new Vue({
  el: '#app',
  data: {
    op: 1,
    started: false
  },
  methods: {
    startOrReset() {
      if (this.started) {
        this.op = 1;
      } else {
        setInterval(() => {
          this.op -= 0.1;
          if (this.op < 0) {
            this.op = 0;
          }
        }, 1000);
        this.started = true;
      }
    }
  }
});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <textarea :style="{opacity: op}" @keydown="startOrReset">
    Type something here before I disappear!
  </textarea>
</div>

Upvotes: 2

mitopalov
mitopalov

Reputation: 88

```

!javascript

clearInterval

``` should have done the trick. Can you show how you used it?

Upvotes: -1

Related Questions