[英]vue.js: how to handle click and dblclick events on same element
我有一個帶有單獨事件的 vue 組件,用於單擊/dblclick。 單擊(取消)選擇行,dblclick 打開編輯表單。
<ul class="data_row"
v-for="(row,index) in gridData"
@dblclick="showEditForm(row,$event)"
@click="rowSelect(row,$event)"
>
這樣做,我會在雙擊時觸發 3 個事件。 兩個點擊事件和最后一個 dblclick。 由於點擊事件首先觸發,有沒有辦法(沒有將點擊事件延遲固定數量的毫秒)來停止雙擊點擊事件的傳播?
在這里擺弄
正如評論中所建議的,您可以通過設置一段時間(例如 x)的計時器來模擬 dblclick 事件。
請參閱下面的代碼和工作小提琴。
new Vue({
el: '#app',
data: {
result: [],
delay: 700,
clicks: 0,
timer: null
},
mounted: function() {
console.log('mounted');
},
methods: {
oneClick(event) {
this.clicks++;
if (this.clicks === 1) {
this.timer = setTimeout( () => {
this.result.push(event.type);
this.clicks = 0
}, this.delay);
} else {
clearTimeout(this.timer);
this.result.push('dblclick');
this.clicks = 0;
}
}
}
});
<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");
}
}
})
我認為我有一個更簡單的解決方案(我使用的是 vue-class 但適用相同的原則):
private timeoutId = null;
onClick() {
if(!this.timeoutId)
{
this.timeoutId = setTimeout(() => {
// simple click
}, 50);//tolerance in ms
}else{
clearTimeout(this.timeoutId);
// double click
}
}
它不需要計算點擊次數。
單擊和單擊之間的時間必須很短。
為了獲得點擊和雙擊,只需要一個計數器來承載點擊次數(例如0.2s),當用戶點擊緩慢或執行多次時就足以捕獲用戶的意圖。雙擊或默認情況。
我將如何實現這些功能的代碼留在這里。
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>
我使用這種方法解決同樣的問題。 我使用了一個通過觸發 200 毫秒超時或檢測到第二次點擊來解決的承諾。 它在我最近的網絡應用程序中運行良好。
<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>
組件
// 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;
}
},
@click.stop處理單擊, @dblclick.stop處理雙擊
<v-btn :ripple="false"
class="ma-0"
@click.stop="$emit('editCompleteGrvEvent', props.item)"
@dblclick.stop="$emit('sendCompleteGrvEvent',props.item)">
<v-icon>send</v-icon>
</v-btn>
除非您需要對單個選擇執行昂貴的操作,否則您可以將 rowSelect 改造成切換。 與設置和取消計時器相比,設置一個簡單的數組會更快、更可靠、更直接。 如果單擊事件觸發兩次並不重要,但您可以在編輯功能中輕松處理。
<template>
<ul>
<li :key="index" v-for="(item, index) in items">
<a
:class="{ 'active-class': selected.indexOf(item) !== -1 }"
@click="toggleSelect(item)"
@dblclick="editItem(item)"
>
{{ item.title }}
</a>
<!-- Or use a checkbox with v-model
<label @dblclick="editItem(item)">
<input type="checkbox" :value="item.id" v-model.lazy="selected" />
{{ item.title }}
</label>
-->
</li>
</ul>
</template>
<script>
export default {
data: function () {
return {
items: [
{
id: 1,
title: "Item 1",
},
{
id: 2,
title: "Item 2",
},
{
id: 3,
title: "Item 3",
},
],
selected: [],
};
},
methods: {
editItem(item) {
/*
* Optionally put the item in selected
* A few examples, pick one that works for you:
*/
// this.toggleSelect(item); // If the item was selected before dblclick, it will still be selected. If it was unselected, it will still be unselected.
// this.selected = []; // Unselect everything.
// Make sure this item is selected:
// let index = this.selected.indexOf(item.id);
// if (index === -1) {
// this.selected.push(item.id);
// }
// Make sure this item is unselected:
// let index = this.selected.indexOf(item.id);
// if (index !== -1) {
// this.selected.splice(index, 1);
// }
this.doTheThingThatOpensTheEditorHere(item);
},
toggleSelect(item) {
let index = this.selected.indexOf(item.id);
index === -1
? this.selected.push(item.id)
: this.selected.splice(index, 1);
},
// For fun, get an array of items that are selected:
getSelected() {
return this.items.filter((item) => this.selected.indexOf(item.id) !== -1);
},
},
};
</script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.