Event DOM 事件工具
GB.Event 是一个零依赖的 DOM 事件工具。它基于浏览器原生 Event API,提供统一的事件绑定、主动触发和移除能力,并用 Pointer Events 同时处理鼠标、触摸与触控笔输入。
快速开始
向 GB.Event() 传入 CSS 选择器或 DOM 元素,再调用事件方法注册监听器。所有绑定方法都会返回当前实例,因此可以连续配置多个事件。
GB.Event('#saveButton')
.click(event => {
console.log('保存', event.currentTarget);
})
.enter(() => {
console.log('指针进入按钮');
});
安装与引入
浏览器直接引入
在业务脚本之前引入,之后即可使用全局方法 GB.Event(target)。
<script src="https://cloud.m775.net/js/event.js"></script>
npm 项目
npm i @gentbo/event
import '@gentbo/event';
选择目标元素
GB.Event(target) 创建并返回一个事件操作实例。target 支持以下三种形式:
CSS 选择器内部按选择器查找元素,例如 GB.Event('#button')。HTMLElement直接使用已经取得的 DOM 元素。NodeList接收元素列表,但默认只操作列表中的第一个元素。const bySelector = GB.Event('#button');
const element = document.querySelector('#button');
const byElement = GB.Event(element);
const elements = document.querySelectorAll('.item');
const firstItem = GB.Event(elements); // 只操作第一个元素
如果需要为列表中的每个元素绑定事件,请主动遍历 NodeList:
document.querySelectorAll('.item').forEach(element => {
GB.Event(element).click(handleItemClick);
});
通用事件 API
通用方法适用于工具未提供快捷方法的原生事件,也可用于业务自定义事件。
.set(name, callback, once?)绑定指定名称的事件;once 为 true 时监听器只执行一次。.add(name, callback, once?)set() 的别名,参数与行为完全相同。.remove(name, callback)移除监听器;callback 必须是绑定时使用的同一个函数引用。.run(name, detail?)主动触发事件,可通过 detail 传递自定义数据。.execute(name, detail?)run() 的别名。.start(name, detail?)run() 的别名。const button = GB.Event('#button');
button.set('click', event => {
console.log(event.type);
});
button.run('click');
快捷事件方法
快捷方法的调用形式一致:第一个参数是监听函数,第二个可选参数 once 控制是否只执行一次。
click / click2对应 click / dblclick,用于单击和双击。menu / wheel对应 contextmenu / wheel,用于右键菜单和滚轮输入。down / move / up对应 pointerdown / pointermove / pointerup。enter / leave对应 pointerenter / pointerleave,事件不冒泡。hover / out对应 pointerover / pointerout,会冒泡,进入或离开子元素时也可能触发。keyDown / keyUp对应 keydown / keyup。input / change对应 input / change,用于输入值与选项变化。focus / blur / select对应 focus / blur / select,用于焦点及文本选择。imStart / imUpdate / imEnd对应 compositionstart / compositionupdate / compositionend。submit / reset对应 submit / reset,用于表单提交和重置。GB.Event('#button').click(event => {
console.log('只响应第一次点击');
}, true);
优先使用 Pointer Events
Pointer Events 用一套事件统一鼠标、触摸屏和触控笔输入。相比同时维护 mousedown、touchstart 等多套逻辑,更适合跨桌面端和移动端的交互。
const surface = GB.Event('#drawingSurface');
surface
.down(event => beginDraw(event))
.move(event => continueDraw(event))
.up(event => endDraw(event));
enter()/leave() 不冒泡,适合只关心目标元素边界的场景;hover()/out() 会冒泡,指针经过子元素时也可能触发,请根据页面结构选择。
处理文本输入与输入法
input() 会在输入值变化时触发。处理中文、日文等输入法时,可以结合 Composition Events,避免在文字尚未组合完成时过早执行搜索或校验。
let composing = false;
const search = GB.Event('#search');
search
.imStart(() => {
composing = true;
})
.imEnd(event => {
composing = false;
runSearch(event.target.value);
})
.input(event => {
if (!composing) runSearch(event.target.value);
});
自定义事件与数据传递
先通过 set() 注册自定义事件,再用 run() 触发。传入的对象可从监听器的 event.detail 中读取。
const profile = GB.Event('#profile');
profile.set('user:update', event => {
console.log(event.detail);
});
profile.run('user:update', {
id: 100,
name: 'Gentbo'
});
移除事件监听器
remove() 必须接收绑定时使用的同一个函数引用。匿名函数即使代码相同,也不是同一个函数,无法用于移除原监听器。
function handleClick(event) {
console.log('click', event);
}
const button = GB.Event('#button');
button.click(handleClick);
button.remove('click', handleClick);
表单示例
监听 submit 时,可使用原生事件对象阻止浏览器默认提交,再执行校验或异步请求。
GB.Event('#loginForm').submit(event => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
submitLogin(formData);
});
使用边界
目标不存在选择器没有匹配到元素时,后续事件绑定无法执行;动态页面应在元素创建后再绑定。NodeList默认只使用第一个元素;批量绑定时需要自行遍历。移除监听保留原函数引用,并在组件销毁或页面卸载时移除长期监听器。原生行为阻止默认行为和停止冒泡仍使用 event.preventDefault() 与 event.stopPropagation()。const element = document.querySelector('#box');
if (element) {
GB.Event(element).click(handleClick);
}
兼容性
运行环境需要支持 ES2020、Class Private Field、DOM Event API 和 Pointer Event API。适用于现代 Chrome、Edge、Firefox、Safari,以及微信、支付宝和常见 Chromium 内置浏览器。