@writ/utils
Version:
My tool kit
164 lines (145 loc) • 3.99 kB
JavaScript
import EventModel from './event-model';
import addEvent from './event-add';
import triggerEvent from './event-trigger';
import removeEvent from './event-remove';
const eventList = [];
const mapEvent = function (callback) {
for (let i = 0; i < eventList.length; i++) {
switch (callback(eventList[i], i)) {
case false: return;
case true: continue;
default: break;
}
}
};
/**
* 绑定事件监听
*
* @param {string} type 事件名称
* @param {function} handler 事件处理函数
* @param {*} data 传递给事件对象的数据
*/
function on(type, listener, data, ...args) {
// 确保handler是函数
if (typeof listener !== 'function') {
throw new TypeError('The event handler must be a function.');
}
let pushed;
mapEvent(event => {
pushed = event.target === this && event.type && event.callback === listener;
if (pushed === true) return false;
});
// 避免事件重复绑定
if (pushed) {
return this;
}
const that = this;
const wrapListener = function (event) {
var evt = new EventModel(event, data);
listener.call(that, evt);
};
eventList.push({
target: this,
type: type,
handler: wrapListener,
callback: listener
});
// 将当前的事件处理函数添加到执行队列
addEvent(this, type, wrapListener, ...args);
return this;
}
/**
* 移除指定的事件监听
**/
function off() {
var arg = arguments;
var len = arg.length;
mapEvent(event => {
switch (len) {
case 0:// 一个参数都没提供, 直接清空list
if (event.target === this) {
removeEvent(this, event.type, event.handler);
}
break;
case 1: // 有type,没handler ,这个type的handler全清空
if (event.target === this && event.type === arg[0]) {
removeEvent(this, event.type, event.handler);
}
break;
default:// 有type,也有handler,也有evtlist
if (event.target === this && event.type === arg[0] && event.handler === arg[1]) {
removeEvent(this, event.type, event.handler);
}
break;
}
});
return this;
}
/**
* 绑定执行一次的事件监听
*
* @param {string} type 事件名称
* @param {function} handler 事件处理函数
* @param {*} data 传递给事件模型的数据
**/
function once(type, handler, data) {
if (typeof handler !== 'function') {
throw new Error('The event handler must be a function.');
}
const that = this;
function once(event) {
var evt = new EventModel(event, data);
handler.call(that, evt);
removeEvent(that, type, once);
}
addEvent(this, type, once);
return this;
}
/**
* 主动触发指定的事件监听
*/
function emit() {
var args = arguments;
mapEvent(event => {
switch (len) {
case 0:// 一个参数都没提供, 直接触发当前对象上所有监听器
if (event.target === this) {
triggerEvent(this, event.type, args[0], args[1], args[2], true);
}
break;
case 1: // 有type,触发指定类型的监听函数
if (event.target === this && event.type === args[0]) {
triggerEvent(this, event.type, args[0], args[1], args[2], true); // 挨个触发事件,转发参数
}
break;
default: break;
}
});
return this;
}
/**
* 给DOM元素上增加事件管理器
* 确保target是对象
* @desc 观察者模式
*/
export function bind(target) {
if (typeof target !== 'object' || !target) {
throw new TypeError('The event target must be an object.');
}
target.on = on.bind(target);
target.once = once.bind(target);
target.emit = emit.bind(target);;
target.off = off.bind(target);;
return target;
}
// 确保target是对象
export function unbind(target) {
if (typeof target !== 'object' || !target) {
throw new TypeError('The event object must be an object.');
}
target.on = null;
target.once = null;
target.emit = null;
target.off = null;
return target;
}