计算页面内各模块的曝光时间
栏目: JavaScript · 发布时间: 5年前
内容简介:产品希望看到投放出去的活动页,用户对其页面内的什么信息比较感兴趣,对什么信息完全不感兴趣。=> 计算页面内每模块的停留时间第一次听到这个需求,我的大脑开始疯狂运转,然后想到了plan 1, plan 2, plan3...中间还有很多失败想法我已经忘记了,这里方案三是我最终采用的方法。存在的问题:不同人的代码风格差异性大,该方案不适合这类代码风格
计算一个页面内每个模块的曝光时间(停留时间)
产品希望看到投放出去的活动页,用户对其页面内的什么信息比较感兴趣,对什么信息完全不感兴趣。=> 计算页面内每模块的停留时间
第一次听到这个需求,我的大脑开始疯狂运转,然后想到了plan 1, plan 2, plan3...中间还有很多失败想法我已经忘记了,这里方案三是我最终采用的方法。
方案一:根据页面dom将页面分模块
var bodyChildrenLists = $('body').children() var bodyChildDomLsit = [] var initHeight = 0 for (var i = 0; i < bodyChildrenLists.length; i++) { if (bodyChildrenLists[i].tagName !== 'SCRIPT') { bodyChildDomLsit.push({ className: bodyChildrenLists[i].className, height: bodyChildrenLists[i].offsetHeight }) } }
存在的问题:不同人的代码风格差异性大,该方案不适合这类代码风格
<body> <div class="container"> <div class="header"></div> <div class="nav"></div> <div class="footer"></div> </div> </body>
这种方式很好,就是,,,如果大家的代码风格很一致的情况下使用比较好。
方案二:计算出用户打开页面后的所有行为
var scrollTop = 0 var time = Date.now() window._stayStatus = { // 记录运动轨迹, down > 1 向下移动 down 向上移动, sliderDis 移动距离, time 移动耗时, initDis 初始距离, initTime 初始时间 moveData: [], enterTime: Date.now() } var moveData = window._stayStatus.moveData var currentMoveIndex = 0 function move () { var currentTime = Date.now() var currentScrollTop = $(window).scrollTop() var dis = currentScrollTop - scrollTop var disTime = currentTime - time // 上一次滑动页面和这次滑动页面的时间差大于100ms,就视作用户在某一个段时间做了停留 if (disTime > 100) { if (moveData[currentMoveIndex] && moveData[currentMoveIndex].down === 0) { moveData[currentMoveIndex].time += disTime } else { moveData.push({ down: 0, initTime: time, // initTime表示进入该状态的初始时间 initDis: currentScrollTop, //initDis 表示进入该状态的初始位置 sliderDis: dis, // 在该状态内滑动的距离 time: disTime // 在该状态经历的时间(ms) }) } } else { // 向下滑动 if (dis >= 0) { // 如果之前已经是向下滑动的状态,只需要在原来的数据上累加滑动距离和滑动时间 if (moveData[currentMoveIndex] && moveData[currentMoveIndex].down > 0) { moveData[currentMoveIndex].sliderDis += dis moveData[currentMoveIndex].time += disTime } else { moveData.push({ down: 1, initTime: currentTime, initDis: currentScrollTop, sliderDis: dis, time: disTime }) } } else { if (moveData[currentMoveIndex] && moveData[currentMoveIndex].down < 0) { moveData[currentMoveIndex].sliderDis += dis moveData[currentMoveIndex].time += disTime } else { moveData.push({ down: -1, initTime: currentTime, initDis: currentScrollTop, sliderDis: dis, time: disTime }) } } } currentMoveIndex = moveData.length - 1 time = currentTime scrollTop = currentScrollTop } window.onscroll = function (e) { move() }
根据以上方法获取到的数据如下:
表示:用户在距顶部2px时停留了2728ms后,向下滑动了612px,滑动时间为595ms,然后又在距顶部612px停留了8649ms,最后向上滑动了604px,经历了167ms。
存在的问题:
最后得到的数据量虽然不会很大,但是将这样的数据给数据组分析,存在一定的难度。这是在没有和产品对接时,自己想的办法,有点想复杂了。但是这种方式可以比较生动模拟出用户的行为。
方案三: 固定模块尺寸,计算每模块的停留时间
与我的产品对接了基本的规定:
- 每1300px高度作为为一个模块,进行埋点统计。
- 每屏曝光范围大于400px时作为有效曝光,开始记录时长。
- 每一模块的上报时间均为在模块内滑动时间及静止停留时间加和。
- 设当前模块为模块0,当用户未到达模块1时,反复滑动时间均记做模块0内时间。
- 设当前模块为模块0,当用户到达模块1后又通过滑动行为返回模块0,此时会重新记录一次模块0数据
- 最后一次上报时间为用户离开该页面(进入下一流程页面或关闭浏览器),需统计能够监测到的用户离开行为及场景。
根据以上需求,我做了一个小demo,代码如下:
<!DOCTYPE html> <html lang="en"> <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>Document</title> <script src="//lib04.xesimg.com/lib/jQuery/1.11.1/jquery.min.js"> </script> <script src="//zt.xueersi.com/apStatic/js/qz-rem.js"></script> <style> * { margin: 0; padding: 0; } .section { height: 1300px; border-bottom: 1px solid #f00; box-sizing: border-box; padding-top: 400px; } </style> </head> <body> <div id="app"> <div class="section"> <p>停留时间0:</p> <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 0">{{0}} ---- {{item.time}}</p> </div> <div class="section"> <p>停留时间1:</p> <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 1">{{1}} ---- {{item.time}}</p> </div> <div class="section"> <p>停留时间2:</p> <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 2">{{2}} ---- {{item.time}}</p> </div> <div class="section"> <p>停留时间3:</p> <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 3">{{3}} ---- {{item.time}}</p> </div> <div class="section"> <p>停留时间4:</p> <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 4">{{4}} ---- {{item.time}}</p> </div> <div class="section"> <p>停留时间5:</p> <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 5">{{5}} ---- {{item.time}}</p> </div> <div class="section"> <p>停留时间6:</p> <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 6">{{6}} ---- {{item.time}}</p> </div> </div> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> new Vue({ el: '#app', data: { movedata: [], scrollTop: $(window).scrollTop(), time: Date.now(), stayTime: 0 }, mounted () { // 部分页面存在页面滚动到某一高度时,刷新后页面也会固定在该高度的问题,初始化movedata数据 var index = parseInt(this.scrollTop / 1300) + 1 for (var i = 0; i <= index; i++) { this.movedata.push({ pos: i * 1300, time: 0 }) } window.onscroll = () => { this.scrollTop = $(window).scrollTop() } setInterval(() => { var currentTime = Date.now() var disTime = currentTime - this.time // 计算当前是展现在屏幕中的模块序号,一个屏幕内最多展现两个模块,currentIndex永远指定的是上面的模块 var currentIndex = parseInt(this.scrollTop / 1300) var length = this.movedata.length if (currentIndex + 1 >= length) { for (var i = length; i <= currentIndex + 1; i++) { this.movedata.push({ pos: 1300 * i, time: disTime }) } } else { // 计算当前的滚动高度超出满屏的多少 var modeDis = this.scrollTop - this.movedata[currentIndex].pos // 表示一屏中上面的模块展示区域超过400,可以累加停留时间 if ((1300 - modeDis) > 400) { this.movedata[currentIndex].time += disTime } // 表示一屏中下面的模块展示区域超过400,可以累加停留时间 if (modeDis > 400) { this.movedata[currentIndex + 1].time += disTime } } this.time = currentTime }, 1000) } }) </script> </body> </html>
使用这种方式,movedata的数组长度等于页面内的模块个数
以上所述就是小编给大家介绍的《计算页面内各模块的曝光时间》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Android 曝光采集(商品view曝光量的统计)第二弹
- Android 曝光采集:以商品 view 曝光量的统计为例
- RecyclerView 的曝光统计
- DJI SDK 如何实现曝光锁定
- 拍照聚焦和曝光,AVFoundation 简明教程
- NSA新型APT框架曝光:DarkPulsar
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。