@yqg/multiple-click
Version:
Monitor user's multiple click behavior and report
65 lines (53 loc) • 2.02 kB
text/typescript
import {processTrackingConfig} from './config';
import {trackingHandlerFactory} from './handler';
import {IExposeMultipleClickTrackingConfig, MouseEventHandler} from './type';
import {bindHandler, unbindHandler} from './utils';
/** 可用性检测 */
const availabilityCheck = () => {
const el = document.createElement('div');
el.style.width = '1px';
el.style.height = '1px';
el.style.opacity = '0';
document.body.appendChild(el);
let trigger = false;
const checkHandler: MouseEventHandler = ({target}) => {
if (target === el) {
trigger = true;
}
};
bindHandler(checkHandler);
el.click();
unbindHandler(checkHandler);
document.body.removeChild(el);
if (!trigger) {
// NOTICE: 还有另一种情况:外部代码hack了 EventTarget.prototype.addEventListener,导致监听器没有被绑定
throw new Error(
'请检查是否其他监听器,在捕获阶段触发并调用stopImmediatePropagation,导致“多次点击点击上报”无法正常生效'
);
}
};
/** 开启多次点击上报,暴露给外部调用的入口 */
export const startMultipleClickTracking = async (config: IExposeMultipleClickTrackingConfig) => {
try {
if (config.env === 'dev') {
// 可用性(连通性)检测
availabilityCheck();
}
// 配置检查、解析
const trackingConfig = await processTrackingConfig(config);
if (!trackingConfig) {
return () => {};
}
// 获取监听器
const trackingHandler = trackingHandlerFactory(trackingConfig);
// 绑定监听器
bindHandler(trackingHandler);
// 返回移除监听器的回调
return () => unbindHandler(trackingHandler);
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);
// eslint-disable-next-line @typescript-eslint/no-empty-function
return () => {};
}
};