var visibleY = function(el){
var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height,
el = el.parentNode
// Check if bottom of the element is off the page
if (rect.bottom < 0) return false
// Check its within the document viewport
if (top > document.documentElement.clientHeight) return false
do {
rect = el.getBoundingClientRect()
if (top <= rect.bottom === false) return false
// Check if the element is out of view due to a container scrolling
if ((top + height) <= rect.top) return false
el = el.parentNode
} while (el != document.body)
return true
};
编辑2016-03-26:我've updated the solution to account for scrolling past the element so it'隐藏在可滚动容器的顶部之上 . 编辑2018-10-08:更新以在屏幕上方滚动视图时进行处理 .
2
我需要检查可滚动DIV容器内元素的可见性
//p = DIV container scrollable
//e = element
function visible_in_container(p, e) {
var z = p.getBoundingClientRect();
var r = e.getBoundingClientRect();
// Check style visiblilty and off-limits
return e.style.opacity > 0 && e.style.display !== 'none' &&
e.style.visibility !== 'hidden' &&
!(r.top > z.bottom || r.bottom < z.top ||
r.left > z.right || r.right < z.left);
}
3
我更喜欢使用jQuery expr
jQuery.extend(jQuery.expr[':'], {
inview: function (elem) {
var t = $(elem);
var offset = t.offset();
var win = $(window);
var winST = win.scrollTop();
var elHeight = t.outerHeight(true);
if ( offset.top > winST - elHeight && offset.top < winST + elHeight + win.height()) {
return true;
}
return false;
}
});
所以你可以这样使用它
$(".my-elem:inview"); //returns only element that is in view
$(".my-elem").is(":inview"); //check if element is in view
$(".my-elem:inview").length; //check how many elements are in view
您可以在 scroll 事件函数等中轻松添加此类代码,以便每次用户滚动视图时进行检查 .
9
jQuery Waypoints插件在这里非常好用 .
$('.entry').waypoint(function() {
alert('You have scrolled to an entry.');
});
// this is the target which is observed
var target = document.querySelector('div');
// configure the intersection observer instance
var intersectionObserverOptions = {
root: null,
rootMargin: '150px',
threshold: 1.0
}
var observer = new IntersectionObserver(onIntersection, intersectionObserverOptions);
// provice the observer with a target
observer.observe(target);
function onIntersection(entries){
entries.forEach(entry => {
console.clear();
console.log(entry.intersectionRatio)
target.classList.toggle('visible', entry.intersectionRatio > 0);
// Are we in viewport?
if (entry.intersectionRatio > 0) {
// Stop watching
// observer.unobserve(entry.target);
}
});
}
<script type="text/javascript">
$.fn.is_on_screen = function(){
var win = $(window);
var viewport = {
top : win.scrollTop(),
left : win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};
if( $('.target').length > 0 ) { // if target element exists in DOM
if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
$('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
} else {
$('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
}
}
$(window).scroll(function(){ // bind window scroll event
if( $('.target').length > 0 ) { // if target element exists in DOM
if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
$('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
} else {
$('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
}
}
});
</script>
/**
* returns true if an element is visible, with decent performance
* @param [scope] scope of the render-window instance; default: window
* @returns {boolean}
*/
jQuery.fn.isOnScreen = function(scope){
var element = this;
if(!element){
return;
}
var target = $(element);
if(target.is(':visible') == false){
return false;
}
scope = $(scope || window);
var top = scope.scrollTop();
var bot = top + scope.height();
var elTop = target.offset().top;
var elBot = elTop + target.height();
return ((elBot <= bot) && (elTop >= top));
};
2
怎么样
function isInView(elem){
return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}
之后,一旦元素在视图中,你可以触发你想要的任何东西
$(window).scroll(function(){
if (isInView($('.classOfDivToCheck')))
//fire whatever you what
dothis();
})
function isScrolledIntoView (elem, divID)
{
var docViewTop = $('#' + divID).scrollTop();
var docViewBottom = docViewTop + $('#' + divID).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
6
可滚动div(容器)的简单修改
var isScrolledIntoView = function(elem, container) {
var containerHeight = $(container).height();
var elemTop = $(elem).position().top;
var elemBottom = elemTop + $(elem).height();
return (elemBottom > 0 && elemTop < containerHeight);
}
注意:如果元素大于可滚动div,则此方法无效 .
2
这是一种使用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);
}});
6
我的应用程序中有这样的方法,但它不使用jQuery:
/* Get the TOP position of a given element. */
function getPositionTop(element){
var offset = 0;
while(element) {
offset += element["offsetTop"];
element = element.offsetParent;
}
return offset;
}
/* Is a given element is visible or not? */
function isElementVisible(eltId) {
var elt = document.getElementById(eltId);
if (!elt) {
// Element not found.
return false;
}
// Get the top and bottom position of the given element.
var posTop = getPositionTop(elt);
var posBottom = posTop + elt.offsetHeight;
// Get the top and bottom position of the *visible* part of the window.
var visibleTop = document.body.scrollTop;
var visibleBottom = visibleTop + document.documentElement.offsetHeight;
return ((posBottom >= visibleTop) && (posTop <= visibleBottom));
}
$(document).scroll(function() {
if($("#div2").is(':onScreen')) {
console.log("Element appeared on Screen");
//do all your stuffs here when element is visible.
}
else {
console.log("Element not on Screen");
//do all your stuffs here when element is not visible.
}
});
30 回答
这是我的纯JavaScript解决方案,如果它也隐藏在可滚动容器中,它也可以工作 .
Demo here(尝试调整窗口大小)
编辑2016-03-26:我've updated the solution to account for scrolling past the element so it'隐藏在可滚动容器的顶部之上 . 编辑2018-10-08:更新以在屏幕上方滚动视图时进行处理 .
我需要检查可滚动DIV容器内元素的可见性
我更喜欢使用jQuery expr
所以你可以这样使用它
您可以在
scroll
事件函数等中轻松添加此类代码,以便每次用户滚动视图时进行检查 .jQuery Waypoints插件在这里非常好用 .
site of the plugin上有一些例子 .
使用(“new”)IntersectionObserver API
确定视口中是否有可见元素非常简单有效 . 通过使用观察者,它消除了附加
scroll
事件和手动检查事件回调的需要 .查看浏览器支持表(IE / Safari不支持)
WebResourcesDepot写了a script to load while scrolling,前一段时间使用jQuery . 你可以查看他们的Live Demo Here . 他们功能的牛肉是这样的:
基于this answer的示例,用于检查元素是否可见75%(即,其中少于25%的元素离开屏幕) .
这会考虑元素具有的任何填充,边框或边距以及大于视口本身的元素 .
要调用它,请使用以下内容:
Build this great answer,您可以使用ES2015进一步简化它:
如果您不关心顶部窗外,只关心底部已被查看,这可以简化为
甚至是单行班轮
普通香草检查元素(
el
)是否在可滚动div中可见(holder
)用于jQuery:
我已经为这项任务编写了a component,旨在处理大量元素extremely fast(在慢速移动设备上为1000个元素调整<10ms) .
它适用于您可以访问的每种类型的滚动容器 - 窗口,HTML元素,嵌入式iframe,衍生的子窗口 - 并且在检测到的内容方面非常灵活(full or partial visibility,border box or content box,custom tolerance zone,etc) .
一个巨大的,主要是自动生成的测试套件可确保它像宣传的那样工作,cross-browser .
如果你愿意,可以试一试:jQuery.isInView . 否则,您可能会在源代码中找到灵感,例如: here .
This answer在香草:
这是http://web-profile.com.ua/的另一个解决方案
在JSFiddle中看到它
我改编了这个简短的jQuery函数扩展,您可以随意使用(MIT许可证) .
怎么样
之后,一旦元素在视图中,你可以触发你想要的任何东西
这对我很有用
这里的大多数答案没有考虑到元素也可以被隐藏,因为它被滚动到div的视图之外,而不仅仅是整个页面的视图 .
为了覆盖这种可能性,您基本上必须检查元素是否位于其每个父项的边界内 .
这个解决方案正是如此:
它还允许您指定在每个方向上可见的百分比 .
它没有涵盖由于其他因素而可能被隐藏的可能性,例如
display: hidden
.这应该适用于所有主流浏览器,因为它只使用getBoundingClientRect . 我亲自在Chrome和Internet Explorer 11中测试过它 .
如果你想调整这个在另一个div中滚动项目,
可滚动div(容器)的简单修改
注意:如果元素大于可滚动div,则此方法无效 .
这是一种使用Mootools在水平,垂直或两者中实现相同功能的方法 .
我的应用程序中有这样的方法,但它不使用jQuery:
编辑:这种方法适用于I.E. (至少版本6) . 阅读注释以了解与FF的兼容性 .
到目前为止我找到的最好的方法是jQuery appear plugin . 奇迹般有效 .
您可以使用jquery插件"onScreen"来滚动时检查元素是否在当前视口中 . 当选择器出现在屏幕上时,插件将选择器的":onScreen"设置为true . 这是插件的链接您可以在项目中包含哪些内容 . “http://benpickles.github.io/onScreen/jquery.onscreen.min.js”
您可以尝试以下适用于我的示例 .
HTML代码:
CSS:
我正在寻找一种方法来查看该元素是否即将进入视图,因此通过扩展上面的片段,我设法做到了 . 以为我会留在这里以防万一它会帮助别人
elm =是您要检查的元素在视图中
scrollElement =您可以传递 window 或具有滚动的父元素
offset =如果你希望它在元素在屏幕之前200px之前触发,然后传递200
如果元素的任何部分在页面上可见,则此方法将返回true . 它在我的情况下效果更好,可能会帮助别人 .
修改了已接受的答案,以便元素必须将其显示属性设置为“无”以外的其他内容,以使质量可见 .
这应该是诀窍:
Simple Utility Function 这将允许您调用一个实用程序函数,该函数接受您正在查找的元素,以及您希望元素完全在视图中还是部分在视图中 .
Usage
isScrolledIntoView 是一个非常需要的函数,所以我尝试了它,它适用于不比视口更高的元素,但如果元素比视口更大则不起作用 . 要解决此问题,请轻松更改条件
对此:
在这里看演示:http://jsfiddle.net/RRSmQ/
根据我的要求推荐了Scott Dowding的酷功能 - 这用于查找元素是否刚刚滚动到屏幕中,即它的顶部边缘 .
有一个plugin for jQuery called inview会添加一个新的"inview"事件 .
以下是一些不使用事件的jQuery插件的代码:
我在一个名叫詹姆斯的家伙的评论中发现了这个(http://remysharp.com/2009/01/26/element-in-view-event-plugin/)