jquery插件——检测DOM元素是否在浏览器可视范围之内
2016-03-25 20:42
501 查看
引言
web应用中有很多地方会用到打点,用来检测用户行为,今天就做了个打点相关的需求,为了统计一个广告给用户的展示次数,每次用户请求完成并且渲染完成之后就算一次成功的展示,其实有时候这个广告还没有在用户的可视范围之内,用户需要滑动滚动条才能看见,但已经算了一次成功展示了,显然这里不太合理,这里做了个检测元素是否在可视范围之内的小插件。验证可行性
为了实现这个,我首先想到的就是碰撞检测,把浏览的页面的宽度作为水平坐标,页面的高度作为
垂直的坐标,页面中的一个元素看做一个
矩形物体a,固定在坐标系中,浏览器可视区域看做另一个
矩形物体b,水平和垂直的滚动条滚动事件看作是
矩形物体b在移动,当
矩形物体a出现在可视区域的时候其实就可以抽象为
矩形物体a和
矩形物体b发生了碰撞。
有了这个思路,剩下的就是获取抽象矩形的坐标了,一对左上角和右下角的坐标确定唯一一个矩形,元素矩形的坐标可以这样获得:
var src_begin_left = $("#src").offset().left, src_begin_top = $("#src").offset().top, src_end_left = src_begin_left + $("#src").width(), src_end_top = src_begin_top + $("#src").height();
同样窗体矩形的位置也可以这么确定:
var win_begin_left = $(window).scrollLeft(), win_begin_top = $(window).scrollTop(), win_end_left = win_begin_left + $(window).width(), win_end_top = win_begin_top + $(window).height();
实现碰撞检测,碰撞检测这个思路之前有看过,所以这次一下子就想到这个了,但具体的实现忘了,自己写了好久发现好麻烦,后来查了资料,想起来了,碰撞检测中碰撞的情况有好多,未碰撞的情况就比较少了只有四种(固定一个矩形,另一个矩形在固定矩形的上下左右的时候、最靠近的边缘未发生碰撞才未发生碰撞,所有的情况都可以归类到这种情况的一种),排除了未碰撞的情况,剩下的就是碰撞。
代码
(function($){ $.extend({ //矩形的碰撞检测 /** * x1,y1 第一个矩形的左上角 * x2,y2 第一个矩形的右下角 * x3,y3 第二个矩形的左上角 * x4,y4 第二个矩形的右下角 * * return Boolean true=>碰撞 */ isCollsion: function(x1, y1, x2, y2, x3, y3, x4, y4){ if( (x1 > x3 && x1 > x4) || (x3 > x1 && x3 > x2) || (y1 > y3 && y1 > y4) || (y3 > y1 && y3 > y2) ){ return false; }else{ return true; } } }); /** * opt中包含了两个参数,元素实际位置的偏移 * * return Boolean 是否在可视范围之内 */ $.fn.isVisable = function(opt){ opt = $.extend({ offsetTop: 0, //网页中元素比实际位置在垂直方向的偏移 offsetLeft: 0, //网页中元素比实际位置在水平方向的偏移 addTop: 0, //元素左上角坐标y轴偏移 addRight: 0, //元素右下角坐标x轴偏移 addBottom: 0, //元素右下角坐标y轴偏移 addLeft: 0, //元素左上角坐标x轴偏移 }, opt); var me = $(this), srcInfo = { begin_left: (me.offset().left + opt.offsetLeft + opt.addLeft), begin_top: (me.offset().top + opt.offsetTop + opt.addTop) } srcInfo.end_left = (srcInfo.begin_left + me.width() + opt.addRight); srcInfo.end_top = (srcInfo.begin_top + me.height() + opt.addBottom); winInfo = { begin_left: $(window).scrollLeft(), begin_top: $(window).scrollTop() } winInfo.end_left = (winInfo.begin_left + $(window).width()); winInfo.end_top = (winInfo.begin_top + $(window).height()); //检测是否”碰撞“” return $.isCollsion( srcInfo.begin_left, srcInfo.begin_top, srcInfo.end_left, srcInfo.end_top, winInfo.begin_left, winInfo.begin_top, winInfo.end_left, winInfo.end_top ); } })($);
有了这个就可以测试下了,随便选一个网站,就看百度首页,用chrome打开,按下F12,运行上面代码,然后随便算一个元素进行测试。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/d639ebf3447aeeb7365764a7dd7017f8.gif)
jquery对IE支持的很好了
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/d358ca0607f028bf0dfd0184f4a36390.gif)
=========================================
更新线,想了下,有了偏移还是不够,还有可能会加上缩小放大。
下面这张图是偏移的示意图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/e69e0670da2bc6f6922e8fdb11af0cce.jpg)
下面这张是尺寸变化的示意图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/5e28efa872b91883686b79c3e9e74070.jpg)
相关文章推荐
- 巧用 jQuery 筛选器,避免重复代码
- JQuery倒计时
- 记录--关于Jquery uploadify 不能动态传值的问题(java)
- 1、input hidden change事件失效2、html通过js追加的元素jquery事件失效
- jquery禁用动画
- 二维码篇【一】【JS】使用jquery.qrcode生成二维码
- 3月25日问题解决<jQuery>
- 献给和我合作的过得前端童靴们:jquery源码分析--序2
- JQuery的复选框的attr("checked")一直为undefined问题
- 用jQuery实现搜索框的过滤效果
- 关于jQuery选择器的完成介绍(转载)
- jQuery基础-选择图片并赋值
- 如何判断jquery选择器选择结果是否存在
- jQuery基础-div层的移动
- jQuery操作HTM元素的常见事件
- jquery validate自定义扩展实例,以及一些常用验证
- jqprint 打印网页 jQuery print plugin
- jQuery监听文件上传实现进度条效果
- jqueryUI slider插件
- JQuery 绑定select标签的onchange事件