///
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;