JS 可视区域监听div展示, 曝光上报
在业务需求中会有,曝光上报这样的需求, 需要计算滚动条和页面可视区域来进行计算,直接粘 代码,大家拿去用吧,vue中离开当前页面一定要清空监听.
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>曝光上报计算</title> <!-- <script src="./flexible.js" type="text/javascript" charset="utf-8"></script> --> <style type="text/css"> * { box-sizing: border-box; } li, ul { list-style: none; } .wbox { width: 100%; min-height: 100vh; background: #86A5AD; } .yh4 { width: 100%; height: 200px; background: beige; border-bottom: 1px solid #333333; padding: 20px; display: flex; justify-content: space-between; } .yh4 li { width: 20%; height: 100%; float: left; border: 1px solid #333333; background-color: aquamarine; } .yh2 { width: 100%; height: 200px; background: beige; border-bottom: 1px solid #333333; padding: 20px; display: flex; justify-content: space-between; margin-bottom: 0.266666rem; } .yh2 li { width: 46%; height: 100%; float: left; border: 1px solid #333333; background-color: aqua; } .yh1 { width: 100%; height: 200px; background: beige; border-bottom: 1px solid #333333; padding: 20px; display: flex; justify-content: space-between; margin-bottom: 0.266666rem; } .yh1 li { width: 100%; height: 100%; float: left; border: 1px solid #333333; background-color: aqua; } </style> </head> <body> <div class="wbox"> <ul class="yh1 dom-exposure" data-id="yh1_11" data-id="yh1_11"> <li>id: yh1_11 </li> </ul> <ul class="yh1 dom-exposure" data-id="yh1_21"> <li>id: yh1_21 </li> </ul> <ul class="yh1 dom-exposure" data-id="yh1_31"> <li>id: yh1_31 </li> </ul> <ul class="yh1 dom-exposure" data-id="yh1_41"> <li>id: yh1_41 </li> </ul> <ul class="yh4 dom-exposure" data-id="yh4_1,yh4_12,yh4_13,yh4_14"> <li>id: yh4_1</li> <li>id: yh4_12</li> <li>id: yh4_13</li> <li>id: yh4_14</li> </ul> <ul class="yh2 dom-exposure" data-id="yh2_1,yh2_12"> <li>id: yh2_1</li> <li>id: yh2_12</li> </ul> <ul class="yh4 dom-exposure" data-id="yh4_21,yh4_22,yh4_213,yh4_214"> <li>id: yh4_21</li> <li>id: yh4_22</li> <li>id: yh4_213</li> <li>id: yh4_214</li> </ul> <ul class="yh2 dom-exposure" data-id="yh2_21,yh2_23"> <li>id: yh2_21</li> <li>id: yh2_23</li> </ul> <ul class="yh4 dom-exposure" data-id="yh4_31,yh4_312,yh4_313,yh4_314"> <li>id: yh4_31</li> <li>id: yh4_312</li> <li>id: yh4_313</li> <li>id: yh4_314</li> </ul> <ul class="yh2 dom-exposure" data-id="yh2_31,yh2_32"> <li>id: yh2_31</li> <li>id: yh2_32</li> </ul> </div> </body> </html> <script type="text/javascript"> var timer, m1, m2; var domexposurearr = document.querySelectorAll(".dom-exposure"); console.log(domexposurearr); // 退出和注销时候需要 将 window.onscroll = null; window.onscroll = function() { // 滚动 clearTimeout(timer) // 每次滚动前 清除一次 timer = setTimeout(function() { // 停止滚动时上报 domexposurearr.forEach((eldom) => { if (isElementInViewport(eldom)) { // 曝光上报 console.log(eldom.dataset.id) } }); },500) }; function isElementInViewport(el) { // 判断是否在可视区域 let rect = el.getBoundingClientRect(); let width_st = rect.width / 2, height_st = rect.height / 2; let 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)) ); } </script>