最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

js如何实现元素曝光上报

来源:懂视网 责编:小采 时间:2020-11-27 21:52:39
文档

js如何实现元素曝光上报

js如何实现元素曝光上报:进行数据上报的时候,经常会遇到列表数据曝光上报的问题,只对在当前可视范围内的数据内容进行曝光上报,而对于未在可视范围内的数据不进行曝光上报,等待用户滚动页面或者区域使元素出现在可视范围内时才进行曝光上报。 解决方案 目前针对此类问题,主要有
推荐度:
导读js如何实现元素曝光上报:进行数据上报的时候,经常会遇到列表数据曝光上报的问题,只对在当前可视范围内的数据内容进行曝光上报,而对于未在可视范围内的数据不进行曝光上报,等待用户滚动页面或者区域使元素出现在可视范围内时才进行曝光上报。 解决方案 目前针对此类问题,主要有

进行数据上报的时候,经常会遇到列表数据曝光上报的问题,只对在当前可视范围内的数据内容进行曝光上报,而对于未在可视范围内的数据不进行曝光上报,等待用户滚动页面或者区域使元素出现在可视范围内时才进行曝光上报。

解决方案

目前针对此类问题,主要有两种解决方案。

方案一:监听页面或者区域scroll事件,通过getBoundingClientRect接口取元素的位置与可视窗口进行判断。

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) {
 // 上报的逻辑
}
window.onscroll = function() {
 nodes.forEach(node => {
 if( isElementInViewport(node) ) {
 report(node)
 }
 })
 
}

优点:兼容性好

缺点:

  • 需要关注页面或者区域的scroll事件
  • 频繁的scroll事件,性能问题
  • 方案二:通过 IntersectionObserver 监听元素是否处于可视范围

    function report(node) {
     // 上报的逻辑
    }
    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)
    })
    

    优点:

  • 无须关注 scroll
  • 回调是异步触发,不会频繁触发,性能好
  • 缺点:兼容性不好?

    实际上,针对兼容性问题,w3c 官方提供了对应 polyfill, 因此intersectionObserver用于生产是可行的。

    总结

    笔者在实际运用中,通过 IntersectionObserver 封装了一个简单的调用库,应用于可视化埋点 sdk 中,用于解决元素曝光问题,如下

    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节点
     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
     // 开始观察
     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
    
    

    调用方法:

    function report() {}
    var exposurer = new Exposure((node) => {
     report(node)
    })
    exposurer.observe(".item)
    

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    js如何实现元素曝光上报

    js如何实现元素曝光上报:进行数据上报的时候,经常会遇到列表数据曝光上报的问题,只对在当前可视范围内的数据内容进行曝光上报,而对于未在可视范围内的数据不进行曝光上报,等待用户滚动页面或者区域使元素出现在可视范围内时才进行曝光上报。 解决方案 目前针对此类问题,主要有
    推荐度:
    标签: 如何 元素 js
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top