我通过AJAX加载元素。其中一些只有当你向下滚动页面时才能看到。有什么方法可以知道元素现在是否在页面的可见部分?
当前回答
这个答案的一个更有效的版本:
/**
* Is element within visible region of a scrollable container
* @param {HTMLElement} el - element to test
* @returns {boolean} true if within visible region, otherwise false
*/
function isScrolledIntoView(el) {
var rect = el.getBoundingClientRect();
return (rect.top >= 0) && (rect.bottom <= window.innerHeight);
}
其他回答
推特斯科特道丁的酷功能为我的要求- 这是用来查找元素是否刚刚滚动到屏幕上,即它的上边缘。
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}
这里有一种使用Mootools实现相同目标的方法,可以是水平的、垂直的或两者都有。
Element.implement({
inVerticalView: function (full) {
if (typeOf(full) === "null") {
full = true;
}
if (this.getStyle('display') === 'none') {
return false;
}
// Window Size and Scroll
var windowScroll = window.getScroll();
var windowSize = window.getSize();
// Element Size and Scroll
var elementPosition = this.getPosition();
var elementSize = this.getSize();
// Calculation Variables
var docViewTop = windowScroll.y;
var docViewBottom = docViewTop + windowSize.y;
var elemTop = elementPosition.y;
var elemBottom = elemTop + elementSize.y;
if (full) {
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
&& (elemBottom <= docViewBottom) && (elemTop >= docViewTop) );
} else {
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
},
inHorizontalView: function(full) {
if (typeOf(full) === "null") {
full = true;
}
if (this.getStyle('display') === 'none') {
return false;
}
// Window Size and Scroll
var windowScroll = window.getScroll();
var windowSize = window.getSize();
// Element Size and Scroll
var elementPosition = this.getPosition();
var elementSize = this.getSize();
// Calculation Variables
var docViewLeft = windowScroll.x;
var docViewRight = docViewLeft + windowSize.x;
var elemLeft = elementPosition.x;
var elemRight = elemLeft + elementSize.x;
if (full) {
return ((elemRight >= docViewLeft) && (elemLeft <= docViewRight)
&& (elemRight <= docViewRight) && (elemLeft >= docViewLeft) );
} else {
return ((elemRight <= docViewRight) && (elemLeft >= docViewLeft));
}
},
inView: function(full) {
return this.inHorizontalView(full) && this.inVerticalView(full);
}});
在这个伟大答案的基础上,你可以使用ES2015+进一步简化它:
function isScrolledIntoView(el) {
const { top, bottom } = el.getBoundingClientRect()
return top >= 0 && bottom <= window.innerHeight
}
如果你不关心顶部是否跳出窗口而只关心底部是否被看到,这可以简化为
function isSeen(el) {
return el.getBoundingClientRect().bottom <= window.innerHeight
}
或者甚至是单行语句
const isSeen = el => el.getBoundingClientRect().bottom <= window.innerHeight
这将考虑元素的任何填充、边框或边距,以及大于视口本身的元素。
function inViewport($ele) {
var lBound = $(window).scrollTop(),
uBound = lBound + $(window).height(),
top = $ele.offset().top,
bottom = top + $ele.outerHeight(true);
return (top > lBound && top < uBound)
|| (bottom > lBound && bottom < uBound)
|| (lBound >= top && lBound <= bottom)
|| (uBound >= top && uBound <= bottom);
}
要调用它,可以使用这样的代码:
var $myElement = $('#my-element'),
canUserSeeIt = inViewport($myElement);
console.log(canUserSeeIt); // true, if element is visible; false otherwise
isScrolledIntoView是一个非常必要的函数,所以我尝试了它,它适用于不高于视口的元素,但如果元素比视口大,它就不起作用了。要解决这个问题,只需改变条件
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
:
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
请看这里的演示:http://jsfiddle.net/RRSmQ/