growing.io圈选及热力图功能还是比较好用的,这周调研了它的技术实现,发现其实并不复杂。
演示
演示网址 (https://www.readingblog.cn/tr...
sdk
之前自己实现了一个无埋点sdk (https://github.com/mfaying/we...
也介绍了无埋点的实现原理 (https://juejin.im/post/5dd158...
现在我们在这个sdk的基础上增加圈选及热力图功能。
通信
由于sdk页面在埋点系统中会嵌入在一个iframe里,所以我们必须使sdk具备跨域通信的能力。这里我们使用的是postMessage,sdk会监听埋点系统发送的消息,来决定是否开启圈选或热力图模式。
_addMessageListener = () => {
eventUtil.on(win, 'message', (event) => {
if(event.data){
try {
const data = JSON.parse(event.data);
const { mode, status } = data;
if (mode === MODE.CIRCLE_SELECT) {
if (status === 'on') {
this.mode = mode;
this._autoHoverCollection();
this._appendWLSStyle();
this._removeHeatmapCanvas();
} else if (status === 'off') {
this.mode = '';
this._autoHoverCollectionOff();
this._removeWLSStyle();
}
} else if (mode === MODE.HEATMAP) {
if (status === 'on') {
this.mode = mode;
this._autoHoverCollection();
this._appendWLSStyle();
this._fetchHeatmap().then((res) => {
this._drawHeatmap(res.data.data);
});
} else if (status === 'off') {
this.mode = '';
this._autoHoverCollectionOff();
this._removeWLSStyle();
this._removeHeatmapCanvas();
}
}
} catch (e) {
console.log(e);
}
}
})
}
圈选模式
当开启圈选模式时,sdk会自动采集"hover事件",在页面中插入一段css(元素被圈选时会加上圈选类名,这段css就是圈选类名的样式)
if (status === 'on') {
this.mode = mode;
this._autoHoverCollection();
this._appendWLSStyle();
this._removeHeatmapCanvas();
}
元素hover时会增加一个圈选类名,并阻止页面跳转等默认事件,同时将数据发送给埋点平台。
埋点平台接收到这个数据就可以自主做圈选分析了。
_autoHoverHandle = (e) => {
try {
const { event, targetElement } = getEvent(e);
const assignData = {
et: 'mouseenter',
ed: 'auto_hover',
}
const logData = this._getLogData(e, assignData);
if (this.mode === MODE.CIRCLE_SELECT || this.mode === MODE.HEATMAP) {
this._selectElement(event, targetElement);
this._postMessage(logData);
}
} catch (err) {
console.log(err);
}
}
_selectElement = (event, targetElement) => {
const elems = doc.getElementsByClassName(WLS_CLICK_SELECT);
for (let i = 0, len = elems.length; i < len; i ++) {
elems[i].classList.remove(WLS_CLICK_SELECT);
}
eventUtil.stopDefault(event);
targetElement.classList.add(WLS_CLICK_SELECT);
}
热力图
当开启热力图时会向用户自己配置的heatmapUrl请求当前页面的热力图数据,绘制热力图。
if (status === 'on') {
this.mode = mode;
this._autoHoverCollection();
this._appendWLSStyle();
this._fetchHeatmap().then((res) => {
this._drawHeatmap(res.data.data);
});
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。