vue.js自定義指令實現長按,安卓支持震動
export default {
install(Vue, options = {
time: 1000
}) {
Vue.directive('longpress', {
bind: function (el, binding, vNode) {
// 確保提供的表達式是函數
if (typeof binding.value !== 'function') {
// 獲取組件名稱
const compName = vNode.context.name;
// 將警告傳遞給控制台
let warn = `[longpress:] provided expression '${binding.expression}' is not afunction, but has to be `;
if (compName) {
warn += `Found in component '${compName}' `;
}
console.warn(warn);
}
var startX, startY, startTime;
// 定義變量
let pressTimer = null;
// 定義函數處理程序
// 創建計時器( 1秒后執行函數 )
let start = (e) => {
if (e.type === 'click' && e.button !== 0) {
return;
}
e.preventDefault();
// 記錄下觸發的坐標和時間
startTime = (new Date()).getTime();
startX = e.targetTouches[0].clientX;
startY = e.targetTouches[0].clientY;
/**
* 注意:此處處理長按震動效果,經測試IOS目前不支持震動
**/
if (pressTimer === null) {
pressTimer = setTimeout(() => {
navigator.vibrate = navigator.vibrate
|| navigator.webkitVibrate
|| navigator.mozVibrate
|| navigator.msVibrate;
if (navigator.vibrate) {
// 支持
navigator.vibrate(200);
}
// 執行函數
handler();
}, options.time);
}
};
// 取消計時器
let cancel = (e) => {
/**
* 注意:此處處理與click事件的沖突(小於300ms可以識別為點擊事件的范圍 然后判斷觸摸點的移動距離)
**/
e.preventDefault();
var now = (new Date()).getTime();
if (now - startTime < 300) {
var x = (Math.abs(startX - e.changedTouches[0].clientX) < 30);
var y = (Math.abs(startY - e.changedTouches[0].clientY) < 30);
if (x && y) {
e.changedTouches[0].target.click();
}
}
// 檢查計時器是否有值
if (pressTimer !== null) {
clearTimeout(pressTimer);
pressTimer = null;
}
};
// 運行函數
const handler = (e) => {
// 執行傳遞給指令的方法
binding.value(e);
};
/**
* 注意:禁止瀏覽器長按出菜單
**/
document.oncontextmenu = function (e) {
e.preventDefault();
return false;
};
// 添加事件監聽器
el.addEventListener('mousedown', start);
el.addEventListener('touchstart', start);
// 取消計時器
el.addEventListener('mouseout', cancel);
el.addEventListener('touchend', cancel);
el.addEventListener('touchcancel', cancel);
}
});
}
};
另一種優雅的實現方法