这个问题有 30 多个答案,但没有一个使用我一直在使用的极其简单的纯 JS 解决方案。没有必要仅仅为了解决这个问题而加载 jQuery,因为许多其他人都在推动。
为了判断元素是否在视口内,我们必须首先确定元素在主体内的位置。我们不需要像我曾经认为的那样递归地执行此操作。相反,我们可以使用element.getBoundingClientRect()。
pos = elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top;
这个值是物体顶部和身体顶部之间的 Y 差。
然后我们必须判断元素是否在视图中。大多数实现都会询问整个元素是否在视口内,因此我们将介绍这一点。
首先,窗口的顶部位置是:window.scrollY。
我们可以通过将窗口的高度添加到它的顶部位置来获得窗口的底部位置:
var window_bottom_position = window.scrollY + window.innerHeight;
让我们创建一个简单的函数来获取元素的顶部位置:
function getElementWindowTop(elem){
return elem && typeof elem.getBoundingClientRect === 'function' ? elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top : 0;
}
如果您使用.getBoundingClientRect() 方法向它传递的不是元素,此函数将返回元素在窗口中的顶部位置,或者返回0。这种方法已经存在了很长时间,所以您不必担心您的浏览器不支持它。
现在,我们元素的顶部位置是:
var element_top_position = getElementWindowTop(element);
And or 元素的底部位置是:
var element_bottom_position = element_top_position + element.clientHeight;
现在我们可以通过检查元素的底部位置是否低于视口的顶部位置以及检查元素的顶部位置是否高于视口的底部位置来确定元素是否在视口内:
if(element_bottom_position >= window.scrollY
&& element_top_position <= window_bottom_position){
//element is in view
else
//element is not in view
从那里,您可以执行逻辑以在您的元素上添加或删除 in-view 类,然后您可以稍后在 CSS 中使用过渡效果进行处理。
我非常惊讶我在其他任何地方都没有找到这个解决方案,但我相信这是最干净、最有效的解决方案,而且它不需要你加载 jQuery!