该指令在el-input-number
组件中使用。
当鼠标长按加号或者减号上,数字持续变化。这个效果就是使用v-repeat-click
指令实现的。
源码
import { once, on } from 'element-ui/src/utils/dom';
export default {
bind(el, binding, vnode) {
let interval = null;
let startTime;
// VNode.context 拿到的是组件对象
// apply 第一个参数不传,函数内部this指向window,改变函数内部this的指向,这么写的原因是什么??
const handler = () => vnode.context[binding.expression].apply();
const clear = () => {
if (Date.now() - startTime < 100) {
handler();
}
clearInterval(interval);
interval = null;
};
on(el, 'mousedown', (e) => {
// e.button是按下了鼠标的哪个键。不等于0则是说明按下的不是左键
if (e.button !== 0) return;
// Date 对象的静态方法。返回当前时间距离时间零点(1970年1月1日 00:00:00 UTC)的毫秒数
startTime = Date.now();
// 监听一次 mouseup 事件。在document上监听可以保证不管鼠标移到什么位置,只要抬起都可以执行
once(document, 'mouseup', clear);
clearInterval(interval);
interval = setInterval(handler, 100);
});
}
};
其中这句的apply
作用仍然不懂
const handler = () => vnode.context[binding.expression].apply();
on, off, once 函数
export const on = (function() {
if (!isServer && document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
};
}
})();
export const off = (function() {
if (!isServer && document.removeEventListener) {
return function(element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event) {
element.detachEvent('on' + event, handler);
}
};
}
})();
/* istanbul ignore next */
export const once = function(el, event, fn) {
var listener = function() {
if (fn) {
fn.apply(this, arguments);
}
off(el, event, listener);
};
on(el, event, listener);
};