js如何實(shí)現(xiàn)元素曝光上報(bào)
進(jìn)行數(shù)據(jù)上報(bào)的時(shí)候,經(jīng)常會(huì)遇到列表數(shù)據(jù)曝光上報(bào)的問(wèn)題,只對(duì)在當(dāng)前可視范圍內(nèi)的數(shù)據(jù)內(nèi)容進(jìn)行曝光上報(bào),而對(duì)于未在可視范圍內(nèi)的數(shù)據(jù)不進(jìn)行曝光上報(bào),等待用戶滾動(dòng)頁(yè)面或者區(qū)域使元素出現(xiàn)在可視范圍內(nèi)時(shí)才進(jìn)行曝光上報(bào)。
解決方案
目前針對(duì)此類問(wèn)題,主要有兩種解決方案。
方案一:監(jiān)聽(tīng)頁(yè)面或者區(qū)域scroll事件,通過(guò)getBoundingClientRect接口取元素的位置與可視窗口進(jìn)行判斷。
function isElementInViewport(el) { var rect = el.getBoundingClientRect(); var width_st = rect.width / 2, height_st = rect.height / 2; var innerHeight = window.innerHeight, innerWidth = window.innerWidth; if ( rect.top <=0 && rect.height > innerHeight || rect.left <= 0 && rect.width > innerWidth ) { return rect.left * rect.right <= 0 || rect.top * rect.bottom <= 0 } return ( rect.height > 0 && rect.width > 0 && ( ( rect.top >= 0 && rect.top <= innerHeight - height_st ) || ( rect.bottom >= height_st && rect.bottom <= innerHeight ) ) && ( ( rect.left >= 0 && rect.left <= innerWidth - width_st ) || ( rect.right >= width_st && rect.right <= innerWidth ) ) ); } var nodes = document.querySelectorAll(".item") function report(node) { // 上報(bào)的邏輯 } window.onscroll = function() { nodes.forEach(node => { if( isElementInViewport(node) ) { report(node) } }) }
優(yōu)點(diǎn):兼容性好
缺點(diǎn):
- 需要關(guān)注頁(yè)面或者區(qū)域的scroll事件
- 頻繁的scroll事件,性能問(wèn)題
方案二:通過(guò) IntersectionObserver 監(jiān)聽(tīng)元素是否處于可視范圍
function report(node) { // 上報(bào)的邏輯 } var intersectionObserver = new IntersectionObserver(entries => { entries.forEach(entry => { if( entry.intersectionRatio > 0 ) { report(entry.target) } }) }) var nodes = document.querySelectorAll(".item") nodes.forEach(node => { intersectionObserver.observe(node) })
優(yōu)點(diǎn):
- 無(wú)須關(guān)注 scroll
- 回調(diào)是異步觸發(fā),不會(huì)頻繁觸發(fā),性能好
缺點(diǎn):兼容性不好?
實(shí)際上,針對(duì)兼容性問(wèn)題,w3c 官方提供了對(duì)應(yīng) polyfill, 因此intersectionObserver用于生產(chǎn)是可行的。
總結(jié)
筆者在實(shí)際運(yùn)用中,通過(guò) IntersectionObserver 封裝了一個(gè)簡(jiǎn)單的調(diào)用庫(kù),應(yīng)用于可視化埋點(diǎn) sdk 中,用于解決元素曝光問(wèn)題,如下
require('intersection-observer'); // polyfill class Exposure { constructor(callback) { if (!callback || typeof callback !== 'function') { throw new Error("need callback or selector param") return } this.intersectionObserver = new IntersectionObserver((entries) => { entries.forEach(item => { if (item.intersectionRatio > 0) { if (item.target) { callback(item.target, item) this.intersectionObserver.unobserve(item.target) } } }) }); } observe(selector, ignoreExposured) { if (!this.intersectionObserver || !selector) { return } let nodes = [] if( this.isDOM(selector) ) { // dom節(jié)點(diǎn) nodes = [selector] }else { // 選擇器 nodes = document.querySelectorAll(selector) } if (!nodes.length) { return } nodes.forEach(node => { if (!ignoreExposured && node.__wg__tracker__exposured__) { return } node.__wg__tracker__exposured__ = true // 開(kāi)始觀察 this.intersectionObserver.observe( node ); }) } disconnect() { if (!this.intersectionObserver) { return } this.intersectionObserver.disconnect() } isDOM(obj) { if( !obj ) { return false } if( typeof HTMLElement === 'object' ) { return obj instanceof HTMLElement } if( typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string' ) { return true } return false } } export default Exposure
調(diào)用方法:
function report() {} var exposurer = new Exposure((node) => { report(node) }) exposurer.observe(".item)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
bootstrap可編輯下拉框jquery.editable-select
這篇文章主要介紹了bootstrap可編輯下拉框jquery.editable-select的相關(guān)資料,需要的朋友可以參考下2017-10-10關(guān)于js中e.preventDefault()的具體使用
本文主要介紹了關(guān)于js中e.preventDefault()的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04JavaScript(JS) 壓縮 / 混淆 / 格式化 批處理工具
本工具所有的功能實(shí)現(xiàn)都是由 ttp://jscompress.sinaapp.com/api 處理.(包括現(xiàn)在可以使用的這個(gè)在線壓縮)2010-12-12怎么使用javascript深度拷貝一個(gè)數(shù)組
一般情況下,使用 “=” 可以實(shí)現(xiàn)賦值。但對(duì)于數(shù)組、對(duì)象、函數(shù)等這些引用類型的數(shù)據(jù),這個(gè)符號(hào)就不好使了。下面我們來(lái)詳細(xì)學(xué)習(xí)下吧2019-06-06如何阻止復(fù)制剪切和粘貼事件為了表單內(nèi)容的安全
提交表單內(nèi)容如(密碼)重要信息時(shí),為了安全,需要阻止一些復(fù)制剪切和粘貼事件,下面與大家分享一個(gè)實(shí)例,感興趣的朋友可以參考下哈2013-05-05