浏览量自增

需求分析

微博、空间动态中经常能看到浏览量统计,不同于博客,点击之后浏览量自动加1,这种碎片化的推送信息,浏览次数不能以常规的点击方式来统计,用户可能甚至根本不会点击内容,匆匆一瞥就把滚动条往下滑动了,所以如何设计一个自动统计用户浏览这些零散信息的浏览量,是大有操作空间的。

首先规定用户的什么行为作为一次浏览,考虑用户在每个信息前停留的时间,以及浏览页面的习惯,做出如下规定

如果一条微博或好友动态在用户的屏幕前停留超过2s,那么我们认为这条动态被用户浏览了

你可能会说,“如果动态比较短,比如只有一个字,1s都不用就看完了,难道还非得停留2s,这不就造成了浏览数据量统计的误差吗”,当然,考虑到实际场景,停留的时间可能会根据信息的长短做出相应调整,这是对软件最终实现结果的优化,但是整个实现机制是不会有太大的变动的。上面的规定,换成开发者的角度是下面这样的

如果一个html元素(多为一个div,或者一个组件),在可视区域内停留超过2s,发送请求给后台,告诉后台给该组件绑定的信息浏览量加1

实现思路

  • step1 如何判断一个元素是否在可视区内

图1

如图所示,判断一个元素是否在可视区内的条件就是`y1<=y2&&y3<=y4`,使用这种判断条件,规定了类似图中“心灵鸡汤”这类元素不在可视区内(或者说不完全在可视区内),代码实现如下

html部分

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>浏览量自增</title><style>#count{margin-top: 200px;background: chartreuse;height: 200px;font-size: 40px;line-height: 200px;text-align: center;}body{height: 2000px;overflow: auto;}</style>
</head>
<body><div id="count">浏览量:0</div>
</body>
</html>

效果如下

图2

图中绿色背景的部分作为一条微博正文

判断该部分是否在可视区域内

function isInSight() {var visibleArea = document.documentElement.clientHeight;//屏幕可视区域的高度var ele = document.getElementById('count');//元素相对于文档顶部的距离,即图1中的y2var eleTop = ele.offsetTop;//获取浏览器窗口顶部距离文档顶部的距离(滚动条滚动的距离),即图1中的y1var scrollTop = document.documentElement.scrollTop;return scrollTop <= eleTop && (eleTop + ele.offsetHeight) <= (scrollTop + visibleArea)
}
  • setup2 如何判断div在可视区域内停留了2s

最开始我的想法是,记录div由不在可视区域(false)进入可视区域(true)的时刻t1,再记录由true变为fasle的时刻t2,判断t2-t1的差值是否大于2s,但是这种处理逻辑会造成非常不好的效果,例如,用户在看到最后一条记录的时候,看完之后直接把浏览器关了,那么我就获取不到t2了,并且这种做法在时效性上是很差的,假设用户盯着这条动态看了10min,或者把浏览器切到这个地方去上厕所了,那么获取t2的时刻就非常的晚,这样过很久之后一条动态的浏览次数才会+1,这显然是不能接受的。

所以上面那种做法是不可取的,那么换一种策略,仍然记录t1,在t1时刻的2s之后再去判断div是否在区域内,如果还在,认为它在可视区域内停了2s,否则没有停够2s,但是这种做法仍然有漏洞,例如,用户在2s内快速滑动滚动条,用户在t1+0.1s的时候将一条动态划出了屏幕,在t1+1.9s的时候将这条动态划回了屏幕,此时时间来到t1+2s,该条动态在屏幕内,按照上文所述的逻辑,就会得出该条动态被浏览的错误结论,但是相较方法1,在时效性上是有很大提升的。

最完美的做法应该是这样处理的,利用计时器时刻判断div是否在可视区域内,如果为false,更新时间节点t1,如果为true,计算当前时间与t1差值是否大于2s。

具体实现使用了对象劫持

// 定义一个这样的对象记录组件(div)的相关信息
let obj = {updateTime:null,    // div不在可视区域的时刻,实时更新conut:0,  // 浏览次数,结合后台返回结果isUpdated: false,  // 是否被浏览过,浏览过后不再判断ele:document.getElementById('count'),  // 组件dom对象callback: function () { // 回调函数:设置停留时间超过2s后所做的操作,这里可以进行前后端交互this.ele.innerText = `浏览量:1`console.log('您已经停留超过2s了')}
}Object.defineProperty(obj,'isInSight',{get: function () {return this.isInSight},set: function (newValue) {/* 如果已经浏览过没必要更新*/if(this.isUpdated){return}/*如果不在可视化区域,或者首次运行,更新时间*/if(!newValue || !this.updateTime) {this.updateTime = new Date();} else {// 否则计算时间差const difference = new Date() - this.updateTimeif(difference>2000){this.callback()this.isUpdated = true}}}
})obj.isInSight = isInSight()
//启动计时器
setInterval(()=>{obj.isInSight = isInSight()
});

总结

上面的实现方法依然不算完美,因为计时器是非常损耗性能的,如果使用一个计时器同时更新多个组件的状态,那么只能等到所有的组件都被浏览过一次之后才能去销毁这唯一的一个计时器,如果每个组件的状态更新都使用不同的计时器,等到该组件被浏览之后再销毁,那么创建大量计时器的花销和多个计时器同时运行的损耗也是非常大的。如果可行的话,监听document.documentElement.scrollTop或者ele.offsetTop属性的变化来进行判断或许是不错的尝试,原生dom的属性能否被监听呢?这或许是下一个可以尝试的点。1347

【web】仿微博浏览量自增(判断元素是否在可视区+停留2s事件响应)相关推荐

  1. springboot整合redis实现HyperLogLog统计文章浏览量使用过期策略完成数据库同步

    springboot整合redis实现HyperLogLog统计文章浏览量&&使用过期策略完成数据库同步 本文目录 springboot整合redis实现HyperLogLog统计文章 ...

  2. Robotframework-ride 实例 - 提高文章浏览量 例某个Web

    我爱自动化胜过爱维C 环境搭建 脚本思路: 开启浏览器: 输入CSDN地址: 输入搜索想要刷浏览量的文章名: 点击搜索: 切换窗口,点击文章链接,打开文章阅读页: (共显示三个浏览器标签页): 关闭浏 ...

  3. Android实现动态贴纸,Android开发之仿微博贴纸效果实现——进阶篇

    上个月写了一篇<Android开发之仿微博贴纸效果实现--基础篇>,文章中提到还有一篇进阶篇要写,很早就想动笔了,因中途去维护了开源库<高仿微信图片选择器2.0版本>,导致耽搁 ...

  4. Python数据分析系列之——王一博微博转发量分析

    首先说明一下本人不是王一博粉丝,也不讨厌王一博,只是最近在学习python数据分析,就随便找了一条微博转发量来分析一下,只是刚好抽中了王一博哈~ 但是有些时候的确令人疑惑,为什么wyb随随便便发一条微 ...

  5. Python数据分析系列之——王一博微博转发量分析1 数据说明2 粉丝结构初步分析3 粉丝画像最后的话

    首先说明一下本人不是王一博粉丝,也不讨厌王一博,只是最近在学习python数据分析,就随便找了一条微博转发量来分析一下,只是刚好抽中了王一博哈~ 但是有些时候的确令人疑惑,为什么wyb随随便便发一条微 ...

  6. 转:Tumblr:150亿月浏览量背后的架构挑战

    转:Tumblr:150亿月浏览量背后的架构挑战 by  唐福林  posted on  2012 年 02 月 17 日 导读:和许多新兴的网站一样,著名的轻博客服务Tumblr在急速发展中面临了系 ...

  7. jsp新闻项目(分页评论的维护浏览量)

    目录 一.分页 1.思路分析 2.代码 二.评论的维护 (Oracle)数据库评论表 1.添加评论 2.显示评论 3.删除评论 三.浏览量 一.分页 1.思路分析 当我们的数据库数据过多时,一个页面会 ...

  8. Tumblr:150亿月浏览量背后的架构挑战

    Tumblr:150亿月浏览量背后的架构挑战 2013/04/08 · IT技术, 开发 · 9.9K 阅读 · HBase, Tumblr, 架构 英文原文:High Scalability,编译: ...

  9. Python selenium插件使用 可刷浏览量

    常见selenium 代码及含义: Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Selenium 可以直 ...

最新文章

  1. asp.net oracle参数传递,asp.net – Oracle参数问题中的链接数据库
  2. Java 文件及文件夹复制
  3. Gartner:缺乏技术人才将影响企业数字化转型
  4. c语言中整型数组如何初始化,C语言数组空间的初始化详解
  5. html 放到底部,html – 将元素放在页面底部
  6. tcp/ip源代码(17)——ip_fragment
  7. Java——用户激活邮件工具类
  8. python画圆形螺旋线_在PDMS中使用python直接生成管口方位图(开源分享第三集)...
  9. 英雄无敌Ⅲ之游戏修改器DIY
  10. 字符集详解(学习,看一篇就够了)
  11. Gut Microbes:肠道微生物谱的改变与孤独症谱系障碍的异常神经递质代谢活动相关...
  12. 如何制作一个横版格斗过关游戏_地下城与勇士M电脑版,如何在模拟器上使用键鼠操作...
  13. 计讯物联环保数采仪全系列产品为节能降耗减碳贡献绿色力量
  14. 诺丁汉为满足当地需求新建一个数据中心
  15. B0505S-1WR3 隔离模块DC/DC
  16. IDEA导入JUnit测试类
  17. 面试题-redis数据类型
  18. 13_Android的进度条
  19. 2022擎创夏洛克AIOps智慧运营平台白皮书正式发布!
  20. dcloud 5+、uni-app下载到外层目录

热门文章

  1. 微星冲锋坦克Pro GP76 2022款评测
  2. mac更新系统后Git不能用,提示missing xcrun at
  3. CISSP认证流程2
  4. python抽签代码_python3 实现口罩抽签的功能
  5. 医药电商政策有望松绑,市场或迎来爆发期
  6. 我的世界盒子下载|我的世界盒子下载
  7. ps ctrl shift alt t不能复制
  8. 利用电脑QQ自带的文字识别工具,识别文字和翻译英文(小技巧,节省打字时间)
  9. html+css 练习 制作快手首页
  10. 软件经验|使用消费级无人机干测绘(三)Pix4Dmapper软件介绍