几乎全部的项目都要解决这样一个问题:判断一个元素是否出如今浏览器窗口中?由于经过它咱们能够极大的优化项目的性能,进而提高用户的的体验。javascript
所涉及的业务实现,比较常见的就是电商平台或者是图片展现类的网站。电商网站,如:淘宝、京东等;图片展现类,如:花瓣,pinterest。css
涉及的技术,如:lazyload技术动态的加载图片(元素),无限加载技术,包括基于骨架屏技术加载静态资源。前端
data-src
属性的地址,但这里不必定是data-src
属性,也多是srcset
,pinterest中就是这样作的,固然你也能够定义成任何你喜欢的,这只是其中的一种方式;另外一种是判断元素是否出如今浏览器窗口中以后,而后加载一个HTML代码块,小米商城官网就是这样实现的,固然也有其余一些也是这样作的,这里就不一一作介绍了。加载更多
这个代码块是否出如今浏览器窗口中,若是在,就向容器代码块中追加必定数量的相关代码块,这时 加载更多
这个代码块就会被挤压出到浏览器窗口以外。固然有些无限加载技术也使用lazyload。这些业务和技术的目的都是为了为了解决低网速状况下使用web应用,若是页面内内容没有加载,那么就会形成低用户体验。java
这些业务和使用的技术基本上都用了 判断页面的元素是否出如今浏览器窗口中
。jquery
如今通用的是基于浏览器的窗口的判断
那么何为基于浏览器窗口的判断呢?这要经过DOM的API .getBoundingClientRect()
,获取目标元素距离浏览器窗口的位置坐标(top, left) 或者(x, y)坐标,因此说是基于浏览器窗口的。咱们能够拖动浏览器的滚动条来使目标元素从浏览器的顶端进入浏览器窗口(这能够判断上边界),也能够从浏览器的底部进入浏览器窗口(这能够判断下边界),而这正好是判断目标元素进入浏览器窗口的边界。git
上边界:github
目标元素的底边恰好和浏览器的顶部重合,当滚动条向下滚动,目标元素从底部开始一点点的出现,直到目标元素整个出如今浏览器窗口,反之,则逐渐远离。若是目标元素高度大于浏览器窗口的高度,那么浏览器窗口内就不不出现整个目标元素,而只会出现部分,基于这种状况衍生了一种目标元素背景图片的滚动动画。可参考苹果官网。web
下边界:浏览器
目标元素的顶部恰好和浏览器的底部重合,当滚动条向上滚动,目标元素从顶部部开始一点点的出现,直到目标元素整个出如今浏览器窗口,反之,则逐渐远离。app
咱们能够浏览器的滚动条向下滚动(也能够按照向下滚动,答案相似)写出以下的代码:
var clienRect = el.getBoundingClientRect(); if (clientRect.top > -clientRect.width && clientRect.top < window.innerHeight) {} // 或者 if (clientRect.bottom > 0 && clientRect.top =< window.innerHeight) {}
有的同窗可能会问,是否是窗口的高度小于目标元素的高度,或者窗口的高度大于目标元素的高度都这样都同样呢?我想说同样,由于这里是根据两个边界得出的结论。
上面的判断包括目标元素的部分出如今浏览器窗口,那么如何判断整个目标元素出如今浏览器的窗口中呢?可参考以下的代码:
var clienRect = el.getBoundingClientRect(); if (clientRect.top > 0 && clientRect.top < window.innerHeight - clientRect.width) {} // 或者 if (clientRect.top >= 0 && clientRect.bottom > window.innerHeight) {}
兼容性可参考can i use
基于document文档的顶部来判断
这里要使用的是DOM元素的 .offsetTop
来计算目标元素的顶部边界到document文档的顶部边界的距离,使用window的 .pageYoffset
来计算当浏览器滚动条滚动时document文档卷起的高度,经过比较这两个高度,咱们就能够轻松的判断目标元素是否出如今浏览器窗口内。
当目标元素的上边界和浏览器窗口的下边界重合,目标元素的 offsetTop
是个定值,因此此时document文档卷起的高度和目标元素的 offsetTop
之间存在这样一个等式:window.innerHeight + window.pageYoffset = el.offsetTop
。若继续向下滚动浏览器的滚动条,目标元素将出如今浏览器当中,咱们都知道 window.pageYoffset
的值将继续变大,因为 el.offsetTop
和 window.innerHeight
都是个定值,因此咱们能够获得这样一个边界条件,当 window.pageYoffset > el.offsetTop - window.innerHeight
,目标元素从浏览器窗口的底部逐渐出现。
当浏览器的滚动条继续向上滚动会出现目标元素的下边界和浏览器窗口的上边界重合的状况,当继续向下滚动滚动条元素将从浏览器窗口消失,此时存在这样一个等式:window.pageYoffset + el.offsetHeight = el.offsetTop
,因此很明显,若是 window.pageYoffset
的值继续增大,目标元素将消失与浏览器窗口,所以,很明显,只有 window.pageYoffset < el.offsetTop - el.offsetHeight
目标元素才会出如今浏览器窗口内。
参考代码以下:
if (window.pageYoffset > el.offsetTop - window.innerHeight && window.pageYoffset < el.offsetTop - el.offsetHeight) {}
固然,上面的是目标元素部分或总体出如今浏览器窗口的判断条件,若是是整个目标元素,方法同上,可参考下面的代码:
if (window.pageYoffset > el.offsetTop - window.innerHeight - el.offsetHeight && window.pageYoffset < el.offsetTop) {}
虽然这种方法也能够,但它的浏览器兼容性不如第一种。