一直以来,检测元素在浏览器视窗口内不是件容易的事,不少解决方案都不能很准确的判断,计算量也有可能拖慢网站性能。
可是不少场景都须要用到:javascript
- 当页面滚动时,懒加载图片或其余内容。
- 实现“可无限滚动”网站,也就是当用户滚动网页时直接加载更多内容,无需翻页。
- 为计算广告收益,检测其广告元素的曝光状况。
- 根据用户是否已滚动到相应区域来灵活开始执行任务或动画。
监听浏览器滚动事件scroll
,对每一个目标元素执行Element.getBoundingClientRect(),getBoundingClientRect
方法返回元素的大小及其相对于视口的位置。 此方法可获取整个网页左上角定位 ,及距浏览器顶部的或左侧的距离,而后用innerHeight
、innerwidth
等获得视窗大小,以此相减来判断是否在视窗范围内。java
具体代码以下:https://codepen.io/raoenhui/pen/BGBYpXjquery
还有其余检测原理大多都是经过计算获得,可是下面我将要介绍由浏览器自带方法检测元素是否在视窗内。git
Intersection observer 容许你配置一个回调函数,每当target
进入浏览器视窗时,触发回调函数。github
源码地址:https://codepen.io/raoenhui/pen/XoVEjKchrome
var options = { root: document.querySelector('#scrollArea'), rootMargin: '0px', threshold: 1.0 } var callback = function(entries, observer) { /* Content excerpted, show below */ }; var observer = new IntersectionObserver(callback, options);
options 配置项数组
- root 目标元素。默认使用浏览器视口作为root
- rootMargin root元素的外边距。
- threshold 阈值。能够是单一的number也能够是number数组,通常取1。
callback 回调函数浏览器
源码地址:https://codepen.io/raoenhui/pen/xQKPaKapp
target元素和root元素相交程度达到该值的时候IntersectionObserver注册的回调函数将会被执行。
若是你只是想要探测当target元素的在root元素中的可见性超过50%的时候,你能够指定该属性值为0.5。若是你想要target元素在root元素的可见程度每多25%就执行一次回调,那么你能够指定一个数组[0, 0.25, 0.5, 0.75, 1]。默认值是0(意味着只要有一个target像素出如今root元素中,回调函数将会被执行)。该值为1.0含义是当target彻底出如今root元素中时候 回调才会被执行。函数
插件jquery_lazyload
懒加载就是用到了此方法,
源码地址:https://github.com/tuupola/jquery_lazyload
this.observer = new IntersectionObserver(function(entries) { entries.forEach(function (entry) { if (entry.intersectionRatio > 0) { self.observer.unobserve(entry.target); let src = entry.target.getAttribute(self.settings.src); let srcset = entry.target.getAttribute(self.settings.srcset); if ("img" === entry.target.tagName.toLowerCase()) { if (src) { entry.target.src = src; } if (srcset) { entry.target.srcset = srcset; } } else { entry.target.style.backgroundImage = "url(" + src + ")"; } } }); }, observerConfig);
兼容性chrome
基本支持,可是意外的是safari
支持性很差,用到的小伙伴们要注意这点了,兼容性具体看下图:
- 官方连接[Intersection Observer API
Happy coding .. :)