事件 API
tui-entine 提供了完整的事件系统,支持触摸事件和点击事件。
事件类型
touchstart
触摸开始事件。当用户手指开始触摸屏幕时触发。
示例:
ts
element.addEventListener("touchstart", (event: ITuiTouchEvent) => {
console.log("触摸开始", event.clientX, event.clientY);
});touchmove
触摸移动事件。当用户手指在屏幕上移动时触发。
示例:
ts
element.addEventListener("touchmove", (event: ITuiTouchEvent) => {
console.log("触摸移动", event.clientX, event.clientY);
});touchend
触摸结束事件。当用户手指离开屏幕时触发。
示例:
ts
element.addEventListener("touchend", (event: ITuiTouchEvent) => {
console.log("触摸结束", event.clientX, event.clientY);
});click
点击事件。当用户快速点击元素时触发(触摸持续时间 < 300ms 且移动距离 < 10px)。
示例:
ts
element.addEventListener("click", (event: ITuiTouchEvent) => {
console.log("元素被点击", event.clientX, event.clientY);
});事件对象
事件对象 ITuiTouchEvent 包含以下属性和方法:
属性
| 属性 | 类型 | 描述 |
|---|---|---|
type | string | 事件类型('touchstart', 'touchmove', 'touchend', 'click') |
target | ITuiElement | 触发事件的元素 |
currentTarget | ITuiElement | 当前处理事件的元素 |
timeStamp | number | 事件发生的时间戳 |
nativeEvent | UniEvent | 原生事件对象 |
clientX | number | 客户端 X 坐标 |
clientY | number | 客户端 Y 坐标 |
x | number | 触摸点 X 坐标 |
y | number | 触摸点 Y 坐标 |
pageX | number | 页面 X 坐标 |
pageY | number | 页面 Y 坐标 |
offsetX | number | 元素内 X 偏移 |
offsetY | number | 元素内 Y 偏移 |
changedTouches | ITuiTouchEvent[] | 触摸点数组 |
方法
| 方法 | 描述 |
|---|---|
stopPropagation() | 停止事件冒泡 |
preventDefault() | 阻止默认行为 |
事件处理
添加事件监听器
使用 addEventListener 方法为元素添加事件监听器:
ts
const listenerId = element.addEventListener("click", (event) => {
console.log("元素被点击");
});移除事件监听器
使用 removeEventListener 方法移除事件监听器:
ts
element.removeEventListener(listenerId);事件冒泡
事件会从触发元素向上冒泡到父元素,除非调用 stopPropagation() 方法阻止:
ts
element.addEventListener("click", (event) => {
console.log("元素被点击");
event.stopPropagation(); // 阻止事件冒泡
});事件委托
利用事件冒泡机制,可以在父元素上监听子元素的事件:
ts
parentElement.addEventListener("click", (event) => {
console.log("点击了元素:", event.target.id);
});触摸事件处理
基本触摸处理
ts
function touchstart(e: any) {
engine.handleTouchEvent(e);
}
function touchmove(e: any) {
engine.handleTouchEvent(e);
}
function touchend(e: any) {
engine.handleTouchEvent(e);
}多点触摸
tui-entine 支持多点触摸,通过 changedTouches 属性可以获取所有触摸点:
ts
element.addEventListener("touchmove", (event) => {
event.changedTouches.forEach((touch: ITuiTouchEvent) => {
console.log("触摸点:", touch.x, touch.y);
});
});事件最佳实践
1. 及时清理事件监听器
当元素不再需要时,应该移除事件监听器以避免内存泄漏:
ts
// 添加监听器
const listenerId = element.addEventListener("click", handleClick);
// 移除监听器
element.removeEventListener(listenerId);2. 使用事件委托
对于多个子元素,使用事件委托可以减少事件监听器的数量:
ts
// 为父元素添加一个监听器
parentElement.addEventListener("click", (event) => {
// 根据 target 判断点击的是哪个子元素
if (event.target.classList.contains("item")) {
console.log("点击了项目:", event.target.id);
}
});3. 合理使用事件冒泡
利用事件冒泡可以简化事件处理逻辑,但要注意避免不必要的事件传播:
ts
// 子元素
childElement.addEventListener("click", (event) => {
console.log("子元素被点击");
// 必要时阻止冒泡
// event.stopPropagation();
});
// 父元素
parentElement.addEventListener("click", (event) => {
console.log("父元素被点击");
});4. 处理触摸和点击
在移动设备上,触摸事件和点击事件可能会同时触发,需要合理处理:
ts
let isTouching = false;
element.addEventListener("touchstart", () => {
isTouching = true;
});
element.addEventListener("click", () => {
if (!isTouching) {
console.log("鼠标点击");
} else {
console.log("触摸点击");
}
isTouching = false;
});性能优化
1. 减少事件监听器数量
尽量使用事件委托,减少直接在每个元素上添加监听器。
2. 防抖和节流
对于频繁触发的事件(如 touchmove),可以使用防抖或节流来优化性能:
ts
// 节流函数
function throttle(func: Function, delay: number) {
let lastCall = 0;
return function (...args: any[]) {
const now = Date.now();
if (now - lastCall >= delay) {
lastCall = now;
return func.apply(this, args);
}
};
}
// 使用节流处理 touchmove
element.addEventListener(
"touchmove",
throttle((event) => {
console.log("触摸移动", event.clientX, event.clientY);
}, 16),
); // 约 60fps3. 避免在事件处理中进行复杂计算
事件处理函数应该尽量简洁,避免执行复杂的计算或 DOM 操作:
ts
element.addEventListener("click", () => {
// 避免复杂计算
setTimeout(() => {
// 复杂操作放在异步中执行
performHeavyCalculation();
}, 0);
});4. 使用 passive 事件监听器
对于不需要阻止默认行为的事件,可以使用 passive 监听器提高性能:
ts
// 注意:tui-entine 目前可能不直接支持 passive 选项
// 但在原生事件处理中可以考虑
window.addEventListener("touchmove", handleTouchMove, { passive: true });常见问题
1. 点击事件不触发
原因:
- 元素可能被其他元素遮挡
- 触摸事件被阻止冒泡
- 触摸持续时间过长或移动距离过大
解决方案:
- 检查元素层级和 z-index
- 确保事件正确传递到引擎
- 确保触摸操作符合点击事件的触发条件
2. 事件触发多次
原因:
- 多次添加相同的事件监听器
- 事件冒泡导致父元素也触发事件
解决方案:
- 确保只添加一次事件监听器
- 合理使用
stopPropagation()
3. 触摸事件卡顿
原因:
- 事件处理函数执行时间过长
- 频繁的 DOM 操作
解决方案:
- 优化事件处理函数
- 使用节流或防抖
- 减少 DOM 操作,使用局部更新
4. 多点触摸不工作
原因:
- 没有正确处理
changedTouches - 触摸事件没有正确传递
解决方案:
- 检查触摸事件传递
- 使用
changedTouches处理多点触摸