/// import * as React from 'react'; import { getDefaultValue } from '../util/date'; import assign from 'object-assign'; class EventTracking extends React.Component { constructor(props: TspComponentEventTrackingProps, state: any) { super(props, state); this.onUnload = this.onUnload.bind(this); } public static defaultProps: TspComponentEventTrackingProps = { options: [] }; /** * 父页面记录 */ public static parentPage: string[] = []; public observers: TspComponentEventTrackingObservers = []; public mutationObserver: MutationObserver; /** * 行为数据统计 */ public data: any = {}; /** * 当前时间 */ public time: number = new Date().getTime(); /** * 是否被销毁 */ public isDestory: boolean = false; /** * 配置观察选项: */ public observeConfig: any = { attributes: true, attributeOldValue: true, attributeFilter: ['data-trackid'] }; /** * 请求发送的参数 */ public sendParams: any = []; public shouldComponentUpdate(): boolean { return false; } public componentDidMount(): void { // Firefox和Chrome早期版本中带有前缀 this.mutationObserver = window['MutationObserver'] || window['WebKitMutationObserver']; if (this.mutationObserver) { const length = this.props.options.length; for (let i = 0; i < length; i++) { const target = document.getElementById(this.props.options[i].id); if (target && this.props.options[i].enable) { const field = this.props.options[i].id; this.data[field] = []; // 创建观察者对象 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (this.props.options[i].trigger !== 'destroy') { this.onMutation(field, target, this.props.options[i]); } }); }); // 传入目标节点和观察选项 observer.observe(target, this.observeConfig); this.observers.push({ observer, field }); } } } window.addEventListener('unload', this.onUnload, false); } public componentWillReceiveProps(nextProps: TspComponentEventTrackingProps): void { if (this.mutationObserver) { const length = nextProps.options.length; for (let i = 0; i < length; i++) { const target = document.getElementById(nextProps.options[i].id); const field = nextProps.options[i].id; if (target && this.props.options[i].enable === false && nextProps.options[i].enable === true) { this.data[field] = []; // 创建观察者对象 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.oldValue && nextProps.options[i].trigger !== 'destroy') { this.onMutation(field, target, nextProps.options[i]); } }); }); // 传入目标节点和观察选项 observer.observe(target, this.observeConfig); this.observers.push({ observer, field }); } } } } public componentWillUnmount(): void { this.onDestroy(); window.removeEventListener('unload', this.onUnload); } /** * 添加数据 */ public dataPush(params: TspComponentEventTrackingDataPushParams, isDestory: boolean): void { const field = params.id; const dataset = params.target.dataset; const datasetTime = parseInt(dataset.time); const dataLength = this.data[field].length; const pageHistory = EventTracking.parentPage; let parentPage; let stopSeconds; if (params.trigger === 'once') { parentPage = pageHistory[pageHistory.length - 2]; } else { parentPage = pageHistory[pageHistory.length - 1]; } if (params.time) { if (params.trigger === 'once') { stopSeconds = params.time - this.time; } else { stopSeconds = params.time - datasetTime; } } else { stopSeconds = dataLength ? datasetTime - new Date(this.data[field][dataLength - 1].createTime).getTime() : datasetTime - this.time; } this.data[field].push({ //id: this.isDestory ? dataset.trackid : dataset.prevtrackid, buildingProjectId: this.props.buildingProjectId, houseId: this.props.houseId, topModule: this.props.topModule, secondaryModule: this.props.secondaryModule, actionName: params.actionName, behaviorName: params.behaviorName, mainType: params.mainType, subType: params.subType, createTime: getDefaultValue(datasetTime, 'string'), detailedData: this.getDetailedData(params.type, dataset), parentPage, //nowPage: pageHistory[pageHistory.length - 1], //pageHistory, stopSeconds }); } /** * 销毁时触发 */ public onDestroy(noRequest?: boolean): void { const length = this.props.options.length; const time = new Date().getTime(); this.isDestory = true; console.log('销毁时:'); for (let i = 0; i < length; i++) { const target = document.getElementById(this.props.options[i].id); const field = this.props.options[i].id; const destroyTrigger = this.props.options[i].destroyTrigger; const trigger = this.props.options[i].trigger; if ((destroyTrigger || trigger === 'once') && target) { if (!this.data[field]) { this.data[field] = []; } if ((!this.data[field].length && trigger === 'once') || destroyTrigger) { this.dataPush({ id: field, target, time, type: this.props.options[i].type, actionName: this.props.options[i].actionName, behaviorName: this.props.options[i].behaviorName, mainType: this.props.options[i].mainType, subType: this.props.options[i].subType, trigger: this.props.options[i].trigger }, true); } } if (this.observers[i]) { this.observers[i].observer.disconnect(); } } if (!noRequest) { console.log(this.data) this.props.request(assign({}, this.props.api, { params: { dataStr: JSON.stringify(this.data) }})); } } /** * 页面被卸载时触发 */ public onUnload(): void { if (!this.isDestory) { this.onDestroy(true); if (navigator && navigator.sendBeacon) { navigator.sendBeacon(this.props.host + this.props.api.api, JSON.stringify({ dataStr: JSON.stringify(this.data) })); } } } /** * Mutation监听事件 */ public onMutation(field: string, target: HTMLElement, options: TspComponentEventTrackingOption): void { console.log('动作触发时:'); this.dataPush({ actionName: options.actionName, behaviorName: options.behaviorName, mainType: options.mainType, subType: options.subType, id: field, target, type: options.type, trigger: options.trigger }, false); console.log(this.data) } /** * 得出详情数据记录 */ public getDetailedData(type: string, dataset: any): any { const id = this.isDestory ? dataset.trackid : dataset.prevtrackid; switch (type) { default: return { value: dataset.trackvalue ? dataset.trackvalue : undefined, id }; } } public render(): JSX.Element { return (
); } } export default EventTracking;