I have a vue component with separate events for click/dblclik. Single click (de)selects row, dblclick opens edit form.
i have a simpler solution i think (i'm using vue-class but same principle apply):
private timeoutId = null;
onClick() {
if(!this.timeoutId)
{
this.timeoutId = setTimeout(() => {
// simple click
}, 50);//tolerance in ms
}else{
clearTimeout(this.timeoutId);
// double click
}
}
it does not need to count the number of clicks.
The time must be short between click and click.
In order to get the click and double click, only one counter is required to carry the number of clicks(for example 0.2s) and it is enough to trap the user's intention when he clicks slowly or when he performs several that would be the case of the double click or default case.
I leave here with code how I implement these features.
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>
I use this approach for the same problem. I use a promise that is resolved either by the timeout of 200ms being triggered, or by a second click being detected. It works quite well in my recent web apps.
<div id="app">
<div
@click="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>
Working fiddle: https://jsfiddle.net/MapletoneMartin/9m62Lrwf/
As suggested in comments, You can simulate the dblclick event by setting up a timer for a certain period of time(say x). If we do not get another click during that time span, go for the single_click_function(). If we do get one, call double_click_function(). Timer will be cleared once the second click is received. It will also be cleared once x milliseconds are lapsed.
See below code and working fiddle.
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;
}
}
}
});
vue Component
// html
<div class="grid-content">
<el-button
@click.native="singleClick"
@dblclick.native="doubleClick"
class="inline-cell">
click&dbclickOnSameElement</el-button>
</div>
// script
<script>
let time = null; // define time be null
export default {
name: 'testComponent',
data() {
return {
test:''
};
},
methods: {
singleClick() {
// first clear time
clearTimeout(time);
time = setTimeout(() => {
console.log('single click ing')
}, 300);
},
doubleClick() {
clearTimeout(time);
console.log('double click ing');
}
}
}
</script>
selectedFolder = ''; // string of currently selected item
folderSelected = false; // preview selected item
selectFolder(folder) {
if (this.selectedFolder == folder) {
// double click
this.folderSelected = false;
this.$store.dispatch('get_data_for_this_folder', folder);
} else {
// single click
this.selectedFolder = folder;
this.folderSelected = true;
}
},