web-dev-qa-db-fra.com

vue.js: comment gérer les événements click et dblclick sur le même élément

J'ai un composant vue avec des événements séparés pour click/dblclik. Un seul clic (de) sélectionne la ligne, dblclick ouvre le formulaire d'édition.

<ul class="data_row"
  v-for="(row,index) in gridData"
  @dblclick="showEditForm(row,$event)"
  @click="rowSelect(row,$event)"
>

En faisant ça, je reçois 3 événements déclenchés en double-cliquant. Deux événements de clic et enfin un clic double. Puisque l'événement de clic se déclenche en premier, existe-t-il un moyen (à moins de différer l'événement de clic pour une quantité fixe de ms) d'arrêter la propagation de l'événement de clic lors d'un double clic?

Violon ici

15
Corwin

Comme suggéré dans les commentaires, vous pouvez simuler l'événement dblclick en configurant une minuterie pour une certaine période de temps (disons x). Si nous n'obtenons pas un autre clic pendant cette période, optez pour la fonction single_click_function (). Si nous en obtenons un, appelez double_click_function (). La minuterie sera effacée une fois le deuxième clic reçu. Il sera également effacé une fois x millisecondes écoulées.

Voir ci-dessous le code et le fonctionnement violon .

new Vue({
    el: '#app',
    data: {
        result: [],
        delay: 700,
        clicks: 0,
        timer: null
    },    
     mounted: function() {
        console.log('mounted');
     },      
     methods: {
        oneClick: function(event){
          this.clicks++ 
          if(this.clicks === 1) {
            var self = this
            this.timer = setTimeout(function() {
              self.result.Push(event.type);
              self.clicks = 0
            }, this.delay);
          } else{
             clearTimeout(this.timer);  
             this.result.Push('dblclick');
             this.clicks = 0;
          }         
        }      
     }
});
12
Saurabh

Le temps doit être court entre le clic et le clic.

Pour obtenir le clic et le double clic, un seul compteur est nécessaire pour transporter le nombre de clics (par exemple 0,2 s) et il suffit de piéger l'intention de l'utilisateur lorsqu'il clique lentement ou lorsqu'il en effectue plusieurs, ce serait le cas du double clic ou cas par défaut.

Je laisse ici avec le code comment j'implémente ces fonctionnalités.

new Vue({
   el: '#app',
   data: {numClicks:0, msg:''},
   methods: {
      // detect click event
      detectClick: function() {
        this.numClicks++;
        if (this.numClicks === 1) {          // the first click in .2s
            var self = this;
            setTimeout(function() {
                switch(self.numClicks) {     // check the event type
                      case 1:
                        self.msg = 'One click';
                        break;
                      default:
                        self.msg = 'Double click';
                }
                self.numClicks = 0;               // reset the first click
            }, 200);                              // wait 0.2s
        } // if
      }  // detectClick function
   }
});
span { color: red }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.0/vue.js"></script>

<div id='app'>
  <button @click='detectClick'>
    Test Click Event, num clicks
    <span>{{ numClicks }}</span>
   </button>
  <h2>Last Event: <span>{{ msg }}</span></h2>
</div>
1
fitorec

J'utilise cette approche pour le même problème. J'utilise une promesse qui est résolue soit par le délai de déclenchement de 200 ms, soit par la détection d'un second clic. Cela fonctionne assez bien dans mes applications Web récentes.

<div id="app">
  <div 
    @click="clicked().then((text) => {clickType = text})" 
    @dblclick="clicked().then((text) => {clickType = text})">
      {{clickType}}
  </div>
</div>

<script>
new Vue({
  el: "#app",
  data: {
    click: undefined,
    clickType: 'Click or Doubleclick ME'
  },
  methods: {
    clicked () {
      return new Promise ((resolve, reject) => {
        if (this.click) {
          clearTimeout(this.click)
          resolve('Detected DoubleClick')
        }
        this.click = setTimeout(() => {
         this.click = undefined
         resolve('Detected SingleClick')
        }, 200)
      })
    }
  }
})
</script>

Violon de travail: https://jsfiddle.net/MapletoneMartin/9m62Lrwf/

1
MartinSRimsbo
<div id="example-1">
 <button v-on:dblclick="counter += 1, funcao()">Add 1</button>
   <p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
 el: '#example-1',
 data: {
   counter: 0
 },
 methods: {
   funcao: function(){
     alert("Sou uma funcao");
   }
 }
})

consultez ce violon de travail https://codepen.io/robertourias/pen/LxVNZX

1
jafar690