浏览量自增

需求分析

微博、空间动态中经常能看到浏览量统计,不同于博客,点击之后浏览量自动加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. Codis 3.2 集群搭建与测试
  2. boost::property_tree
  3. yum源 php7.2,云服务器:CentOS7 yum安装PHP7.2的操作方法
  4. 假如,有这样的异性朋友真不错
  5. python 动态_python实现动态创建类的方法分析
  6. MyEclipse导入新项目后,不能发布到Tomcat
  7. 值得关注的HTML基础
  8. python初心记录二
  9. Python较为经典的53个Python库
  10. leetcode350. 两个数组的交集 II(hashmap)
  11. vs怎么把textbox输入的实数放置变量里_方程的计算机处理96(3)_C++vs
  12. revit二次开发概念_BIM百科 | Revit二次开发入门--创建一个简单的程序
  13. php 用户数,php-获得最高数量,产品/用户数
  14. 特斯拉Model 3再次停工!这一次还是因为自动化机器人……
  15. WCF 基础 契约 和 绑定
  16. NOIP2015运输计划
  17. 专访OneAPM创始人何晓阳:APM将是开发者必备服务
  18. 优化器,sgd,adam等
  19. 单系统 台电x80pro_台电x80 pro (ID:E3E6)安装remix OS系统教程整理
  20. wps ppt 如何批量换背景

热门文章

  1. 通过chrome浏览器调试手机页面(IOS和Android)
  2. 贵州关于职称计算机考试试题,贵州2017年第一次职称计算机考试时间
  3. Python对Excel的常规操作 之 读取,写入(保留原格式写入)
  4. 推荐两种开发者独立博客域名起名方式
  5. “合购团体票”问题设计与结论思考
  6. CameraX 库打开手电筒的两种方式
  7. matlab箱图所有点,MATLAB:多个不同维度的箱线图画在一起
  8. Java就业的方向有哪些-隐藏的小职业~~
  9. Java的主要就业方向?
  10. 比起“悼念”虾米,我更着急的是如何拯救上万张歌单?