掃二維碼與項目經理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯網交流
大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心~

為玉溪等地區(qū)用戶提供了全套網頁設計制作服務,及玉溪網站建設行業(yè)解決方案。主營業(yè)務為成都網站設計、成都網站制作、玉溪網站設計,以傳統(tǒng)方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
如果在做某個平臺的時候,我們需要統(tǒng)計用戶點擊的次數,點擊的區(qū)域,點擊元素,等等,那我們應該怎么去做比較合適呢?
舉個例子,我想在用戶點擊頁面上的每一個元素時,我都能把這個元素的DOM節(jié)點信息記錄下來,并且上報到服務器,便于后面產品那邊的統(tǒng)計用戶喜好~
那我們要怎么去做呢?寫一個公共函數嗎?然后去統(tǒng)一做上報嗎?
我首先寫一個函數,這是一個獲取點擊元素信息的函數,我們可以在點擊的 event 參數中拿到目標元素 target
圖片
const reportDOM = (e: PointerEvent) => {
// 獲取到點擊的目標元素
const el = e.target
// 把目標元素解析成字符串
const detail = htmlElementAsString(el)
// 進行上報
report(detail)
}
// 上報函數
export const report = (detail) => {
request(url, detail)
}
// 解析函數
export function htmlElementAsString(target: HTMLElement): string {
const tagName = target.tagName.toLowerCase();
if (tagName === 'body') {
return '';
}
let classNames = target.classList.value;
classNames = classNames !== '' ? ` class='${classNames}'` : '';
const id = target.id ? ` id="${target.id}"` : '';
const innerText = target.innerText;
return `<${tagName}${id}${classNames !== '' ? classNames : ''}>${innerText}${tagName}>`;
}寫完這幾個函數之后,我們只需要在每一個點擊事件中去插入這個函數即可
const click1 = (e: PointerEvent) => {
reportDOM(e)
// coding....
}
const click2 = (e: PointerEvent) => {
reportDOM(e)
// coding....
}
const click3 = (e: PointerEvent) => {
reportDOM(e)
// coding....
}但是一個頁面中,點擊事件非常多啊,不可能每一個事件中去插入這個函數,非常麻煩
最好的辦法就是把 click 事件掛載在 window 身上,然后根據 elementFromPoint 去計算坐標匹配的元素,進行解析上報
window.addEventListener(
'click',
(e: PointerEvent) => {
// 通過坐標計算出目標元素
const el = getTargetDomByPointerEvent(e);
if (!el) return;
// 把目標元素解析成字符串
const detail = htmlElementAsString(el);
// 進行上報
report(detail);
},
true,
);
// 通過坐標計算目標元素
export const getTargetDomByPointerEvent = (e: PointerEvent) => {
const el = document.elementFromPoint(e.pageX, e.pageY);
if (el) {
return el as HTMLElement;
}
return null;
};我們可以通過配置一個數組 globalClickListeners ,只對我們所需要的 DOM 節(jié)點進行監(jiān)聽上報,
const globalClickListeners = [
{
selector: '.cla', // 選擇器
},
{
elementText: 'report2', // 元素文本
},
{
selector: '.r', // 選擇器 + 元素文本
elementText: 'report3',
},
];那么我們需要對 window 的點擊監(jiān)聽進行改造
window.addEventListener(
'click',
(e: PointerEvent) => {
const el = getTargetDomByPointerEvent(e);
if (!el) return;
if (globalClickListeners.length) {
globalClickListeners.forEach(({ selector, elementText, data = '' }) => {
if (selector) {
// 選擇器的情況
const els = document.querySelectorAll(selector);
// 點擊元素是否包含所屬選擇器范圍
const isIncludes = [...(els as unknown as any[])].includes(el);
// 包含則上報
if (isIncludes) {
const detail = htmlElementAsString(el);
// 進行上報
report(detail);
}
} else if (el.textContent === elementText) {
// 文本相同情況
const detail = htmlElementAsString(el);
// 進行上報
report(detail);
}
});
}
},
true,
);其實上面就是埋點庫中,全局點擊上報的一種解決方案,看似小問題,但是其實面試了這么多人,感覺只有很少一部分人能回答的比較好~
我是林三心

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯網交流