如何判断一个DOM元素在当前视口中是否可见?

有没有一种有效的方法来判断DOM元素(在HTML文档中)是否当前可见(出现在视口中 )?

(关于Firefox的问题)

更新:时间stream逝,所以我们的浏览器。 这种技术不再被推荐 ,如果你不需要支持IE <7,你应该使用@ Dan的解决scheme( https://stackoverflow.com/a/7557433/5628 )。

原始解决scheme(现已过时):

这将检查元素在当前视口中是否完全可见:

function elementInViewport(el) { var top = el.offsetTop; var left = el.offsetLeft; var width = el.offsetWidth; var height = el.offsetHeight; while(el.offsetParent) { el = el.offsetParent; top += el.offsetTop; left += el.offsetLeft; } return ( top >= window.pageYOffset && left >= window.pageXOffset && (top + height) <= (window.pageYOffset + window.innerHeight) && (left + width) <= (window.pageXOffset + window.innerWidth) ); } 

您可以简单地修改它以确定元素的任何部分在视口中是否可见:

 function elementInViewport2(el) { var top = el.offsetTop; var left = el.offsetLeft; var width = el.offsetWidth; var height = el.offsetHeight; while(el.offsetParent) { el = el.offsetParent; top += el.offsetTop; left += el.offsetLeft; } return ( top < (window.pageYOffset + window.innerHeight) && left < (window.pageXOffset + window.innerWidth) && (top + height) > window.pageYOffset && (left + width) > window.pageXOffset ); } 

现在大多数浏览器都支持getBoundingClientRect方法,这已经成为最佳实践。 使用旧的答案是非常缓慢 , 不准确,并有一些错误 。

select正确的解决scheme几乎从不精确 。 你可以阅读更多关于它的错误。


此解决scheme已在IE7 +,iOS5 + Safari,Android2 +,Blackberry,Opera Mobile和IE Mobile 10上进行testing


 function isElementInViewport (el) { //special bonus for those using jQuery if (typeof jQuery === "function" && el instanceof jQuery) { el = el[0]; } var rect = el.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ ); } 

如何使用:

你可以确定上面给出的函数在被调用的时候返回正确的答案,但是跟踪元素的可见性作为一个事件呢?

将以下代码放在<body>标记的底部:

 function onVisibilityChange(el, callback) { var old_visible; return function () { var visible = isElementInViewport(el); if (visible != old_visible) { old_visible = visible; if (typeof callback == 'function') { callback(); } } } } var handler = onVisibilityChange(el, function() { /* your code go here */ }); //jQuery $(window).on('DOMContentLoaded load resize scroll', handler); /* //non-jQuery if (window.addEventListener) { addEventListener('DOMContentLoaded', handler, false); addEventListener('load', handler, false); addEventListener('scroll', handler, false); addEventListener('resize', handler, false); } else if (window.attachEvent) { attachEvent('onDOMContentLoaded', handler); // IE9+ :( attachEvent('onload', handler); attachEvent('onscroll', handler); attachEvent('onresize', handler); } */ 

如果你做任何DOM修改,他们当然可以改变你的元素的可见性。

指南和常见的陷阱:

也许你需要跟踪页面缩放/移动设备捏? jQuery应该处理缩放/捏交叉浏览器,否则第一或第二个链接应该帮助你。

如果修改DOM ,则会影响元素的可见性。 你应该控制它并手动调用handler() 。 不幸的是,我们没有跨浏览器的onrepaint事件。 另一方面,它允许我们进行优化,并仅对DOM修改进行重新检查,这些修改可能会改变元素的可见性。

永远不要在jQuery $(document).ready()里面使用它,因为现在没有保证CSS被应用了。 你的代码可以在你的CSS硬盘本地工作,但是一旦放在远程服务器上就会失败。

DOMContentLoaded被激发之后, 样式被应用 ,但是图像尚未加载 。 所以,我们应该添加window.onload事件监听器。

我们无法捕捉缩放/捏事件。

最后的手段可能是以下代码:

 /* TODO: this looks like a very bad code */ setInterval(handler, 600); 

如果您关心网页上的选项卡是否处于活动状态并可见,则可以使用非常棒的functionpageVisibiliy HTML5 API。

TODO:这种方法不能处理两种情况:

Dan提供的答案有一些问题,可能会使其成为某些情况下不适合的方法。 其中一些问题在接近底部的答案中被指出,他的代码会给出下列元素的误报:

  • 隐藏在被testing者面前的另一个元素
  • 在父母或祖先元素的可见区域之外
  • 通过使用CSS clip属性隐藏的元素或其子元素

这些限制在以下简单testing结果中得到certificate:

测试失败,使用isElementInViewport

解决scheme: isElementVisible()

下面是这些问题的解决scheme,下面的testing结果和代码的一些部分的解释。

 function isElementVisible(el) { var rect = el.getBoundingClientRect(), vWidth = window.innerWidth || doc.documentElement.clientWidth, vHeight = window.innerHeight || doc.documentElement.clientHeight, efp = function (x, y) { return document.elementFromPoint(x, y) }; // Return false if it's not in the viewport if (rect.right < 0 || rect.bottom < 0 || rect.left > vWidth || rect.top > vHeight) return false; // Return true if any of its four corners are visible return ( el.contains(efp(rect.left, rect.top)) || el.contains(efp(rect.right, rect.top)) || el.contains(efp(rect.right, rect.bottom)) || el.contains(efp(rect.left, rect.bottom)) ); } 

通过testing: http : //jsfiddle.net/AndyE/cAY8c/

结果是:

通过测试,使用isElementVisible

补充笔记

然而,这种方法并不是没有其自身的限制。 例如,即使前面的元素实际上并没有隐藏任何部分,在同一位置被testing的元素比在另一元素上具有更低的z索引将被标识为隐藏。 尽pipe如此,这种方法在Dan的解决scheme没有涵盖的某些情况下有其用处。

element.getBoundingClientRect()document.elementFromPoint()都是CSSOM工作草案规范的一部分,并且至less在IE 6及更高版本和大多数桌面浏览器中都支持很长时间(尽pipe并不完美)。 有关这些function的更多信息,请参阅Quirksmode 。

contains()用于查看document.elementFromPoint()返回的元素是否是我们要testing可见性的元素的子节点。 如果返回的元素是相同的元素,它也返回true。 这只是使检查更健壮。 它在所有主stream浏览器都支持,Firefox 9.0是最后一个添加它的地方。 对于较早的Firefox支持,请查看此答案的历史logging。

如果你想要在元素周围testing更多的可见性点,也就是说,为了确保元素的覆盖范围不超过50%,那么调整答案的最后部分不会太多。 但是,请注意,如果您检查每个像素以确保其100%可见,则可能会非常慢。

我试了丹的答案, 用于确定边界的代数是不正确的。 ryanve的答案更接近,但被testing的元素应该在视口内至less有1个像素,所以试试这个函数:

 function isElementInViewport(el) { var rect = el.getBoundingClientRect(); return rect.bottom > 0 && rect.right > 0 && rect.left < (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */ && rect.top < (window.innerHeight || document.documentElement.clientHeight) /* or $(window).height() */; } 

有一个名为inview的 jQuery插件可以完成这项工作

作为公共服务:
丹的答案是正确的计算(元素可以>窗口,特别是在手机屏幕上),正确的jQuerytesting,以及添加isElementPartiallyInViewport:

顺便说一句,window.innerWidth和document.documentElement.clientWidth之间的区别是clientWidth / clientHeight不包括滚动条,而window.innerWidth / Height。

 function isElementPartiallyInViewport(el) { //special bonus for those using jQuery if (typeof jQuery !== 'undefined' && el instanceof jQuery) el = el[0]; var rect = el.getBoundingClientRect(); // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 } var windowHeight = (window.innerHeight || document.documentElement.clientHeight); var windowWidth = (window.innerWidth || document.documentElement.clientWidth); // http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0); var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0); return (vertInView && horInView); } // http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport function isElementInViewport (el) { //special bonus for those using jQuery if (typeof jQuery !== 'undefined' && el instanceof jQuery) el = el[0]; var rect = el.getBoundingClientRect(); var windowHeight = (window.innerHeight || document.documentElement.clientHeight); var windowWidth = (window.innerWidth || document.documentElement.clientWidth); return ( (rect.left >= 0) && (rect.top >= 0) && ((rect.left + rect.width) <= windowWidth) && ((rect.top + rect.height) <= windowHeight) ); } function fnIsVis(ele) { var inVpFull = isElementInViewport(ele); var inVpPartial = isElementPartiallyInViewport(ele); console.clear(); console.log("Fully in viewport: " + inVpFull); console.log("Partially in viewport: " + inVpPartial); } 

testing用例

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>Test</title> <!-- <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script src="scrollMonitor.js"></script> --> <script type="text/javascript"> function isElementPartiallyInViewport(el) { //special bonus for those using jQuery if (typeof jQuery !== 'undefined' && el instanceof jQuery) el = el[0]; var rect = el.getBoundingClientRect(); // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 } var windowHeight = (window.innerHeight || document.documentElement.clientHeight); var windowWidth = (window.innerWidth || document.documentElement.clientWidth); // http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0); var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0); return (vertInView && horInView); } // http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport function isElementInViewport (el) { //special bonus for those using jQuery if (typeof jQuery !== 'undefined' && el instanceof jQuery) el = el[0]; var rect = el.getBoundingClientRect(); var windowHeight = (window.innerHeight || document.documentElement.clientHeight); var windowWidth = (window.innerWidth || document.documentElement.clientWidth); return ( (rect.left >= 0) && (rect.top >= 0) && ((rect.left + rect.width) <= windowWidth) && ((rect.top + rect.height) <= windowHeight) ); } function fnIsVis(ele) { var inVpFull = isElementInViewport(ele); var inVpPartial = isElementPartiallyInViewport(ele); console.clear(); console.log("Fully in viewport: " + inVpFull); console.log("Partially in viewport: " + inVpPartial); } // var scrollLeft = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft, // var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; </script> </head> <body> <div style="display: block; width: 2000px; height: 10000px; background-color: green;"> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <input type="button" onclick="fnIsVis(document.getElementById('myele'));" value="det" /> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <div style="background-color: crimson; display: inline-block; width: 800px; height: 500px;" ></div> <div id="myele" onclick="fnIsVis(this);" style="display: inline-block; width: 100px; height: 100px; background-color: hotpink;"> t </div> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <input type="button" onclick="fnIsVis(document.getElementById('myele'));" value="det" /> </div> <!-- <script type="text/javascript"> var element = document.getElementById("myele"); var watcher = scrollMonitor.create( element ); watcher.lock(); watcher.stateChange(function() { console.log("state changed"); // $(element).toggleClass('fixed', this.isAboveViewport) }); </script> --> </body> </html> 

查看使用getBoundingClientRect的边缘的来源。 就像是:

 function inViewport (el) { var r, html; if ( !el || 1 !== el.nodeType ) { return false; } html = document.documentElement; r = el.getBoundingClientRect(); return ( !!r && r.bottom >= 0 && r.right >= 0 && r.top <= html.clientHeight && r.left <= html.clientWidth ); } 

如果元素的任何部分位于视口中,则返回true

我的更短更快的版本。

 function isElementOutViewport (el) { var rect = el.getBoundingClientRect(); return rect.bottom < 0 || rect.right < 0 || rect.left > window.innerWidth || rect.top > window.innerHeight; } 

根据需要添加jsFiddle https://jsfiddle.net/on1g619L/1/

我发现有一个麻烦的是没有一个jQuery中心版本的function可用。 当我遇到丹的解决scheme时,我发现有机会为喜欢用jQuery OO编程的人们提供一些东西。 一定要向上滚动,然后在Dan的代码上打个招呼。 它的好和活泼,像我的魅力。

bada bing bada繁荣

 $.fn.inView = function(){ if(!this.length) return false; var rect = this.get(0).getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); }; //additional examples for other use cases //true false whether an array of elements are all in view $.fn.allInView = function(){ var all = []; this.forEach(function(){ all.push( $(this).inView() ); }); return all.indexOf(false) === -1; }; //only the class elements in view $('.some-class').filter(function(){ return $(this).inView(); }); //only the class elements not in view $('.some-class').filter(function(){ return !$(this).inView(); }); 

用法

 $(window).on('scroll',function(){ if( $('footer').inView() ) { // do cool stuff } }); 

http://www.appelsiini.net/projects/viewport

非常容易使用的插件,只需使用:in-viewport

我发现这里接受的答案对于大多数用例来说过于复杂。 这段代码很好地完成了这个工作(使用JQuery),并区分完全可见和部分可见的元素。

 var element = $("#element"); var topOfElement = element.offset().top; var bottomOfElement = element.offset().top + element.outerHeight(true); var $window = $(window); $window.bind('scroll', function() { var scrollTopPosition = $window.scrollTop()+$window.height(); var windowScrollTop = $window.scrollTop() if( windowScrollTop > topOfElement && windowScrollTop < bottomOfElement) { // Element is partially visible (above viewable area) console.log("Element is partially visible (above viewable area)"); }else if( windowScrollTop > bottomOfElement && windowScrollTop > topOfElement ) { // Element is hidden (above viewable area) console.log("Element is hidden (above viewable area)"); }else if( scrollTopPosition < topOfElement && scrollTopPosition < bottomOfElement ) { // Element is hidden (below viewable area) console.log("Element is hidden (below viewable area)"); }else if( scrollTopPosition < bottomOfElement && scrollTopPosition > topOfElement ) { // Element is partially visible (below viewable area) console.log("Element is partially visible (below viewable area)"); }else{ // Element is completely visible console.log("Element is completely visible"); } }); 

取决于可见的含义。 如果您的意思是当前显示在页面上,给定滚动位置,您可以根据元素y偏移量和当前滚动位置计算它。

根据上面的@ dan的解决scheme( https://stackoverflow.com/a/7557433/5628 ),我有一个清理实施的步骤,以便在同一页面上多次使用它更容易:

 $(function() { $(window).on('load resize scroll', function() { addClassToElementInViewport($('.bug-icon'), 'animate-bug-icon'); addClassToElementInViewport($('.another-thing'), 'animate-thing'); // 👏 repeat as needed ... }); function addClassToElementInViewport(element, newClass) { if (inViewport(element)) { element.addClass(newClass); } } function inViewport(element) { if (typeof jQuery === "function" && element instanceof jQuery) { element = element[0]; } var elementBounds = element.getBoundingClientRect(); return ( elementBounds.top >= 0 && elementBounds.left >= 0 && elementBounds.bottom <= $(window).height() && elementBounds.right <= $(window).width() ); } }); 

我使用它的方式是当元素滚动到视图中时,我添加了一个触发css关键帧animation的类。 这非常直接,当你在页面上有10多件有条件的animation时,效果尤其好。

希望它有帮助!

我认为这是一个更实用的方法。 Dan的答案在recursion上下文中不起作用。

这个函数解决了当你的元素在其他人可滚动div的问题,通过testing任何级别recursion的HTML标签,并停在第一个假。

 /** * fullVisible=true only returns true if the all object rect is visible */ function isReallyVisible(el, fullVisible) { if ( el.tagName == "HTML" ) return true; var parentRect=el.parentNode.getBoundingClientRect(); var rect = arguments[2] || el.getBoundingClientRect(); return ( ( fullVisible ? rect.top >= parentRect.top : rect.bottom > parentRect.top ) && ( fullVisible ? rect.left >= parentRect.left : rect.right > parentRect.left ) && ( fullVisible ? rect.bottom <= parentRect.bottom : rect.top < parentRect.bottom ) && ( fullVisible ? rect.right <= parentRect.right : rect.left < parentRect.right ) && isReallyVisible(el.parentNode, fullVisible, rect) ); }; 

我在这里遇到的所有答案只检查元素是否位于当前视口内 。 但这并不意味着它是可见的
如果给定元素在内容溢出的div内,并且滚动出视图,该怎么办?

为了解决这个问题,你必须检查元素是否被所有父母包含。
我的解决scheme确实如此:

它还允许您指定多less元素必须可见。

 Element.prototype.isVisible = function(percentX, percentY){ var tolerance = 0.01; //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals if(percentX == null){ percentX = 100; } if(percentY == null){ percentY = 100; } var elementRect = this.getBoundingClientRect(); var parentRects = []; var element = this; while(element.parentElement != null){ parentRects.push(element.parentElement.getBoundingClientRect()); element = element.parentElement; } var visibleInAllParents = parentRects.every(function(parentRect){ var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left); var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top); var visiblePercentageX = visiblePixelX / elementRect.width * 100; var visiblePercentageY = visiblePixelY / elementRect.height * 100; return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY; }); return visibleInAllParents; }; 

这个解决scheme忽略了一个事实,即元素可能由于其他事实而不可见,例如opacity: 0

我已经在Chrome和Internet Explorer 11中testing了这个解决scheme。

这是我的解决scheme,它将工作,如果一个元素被隐藏在一个可卷动的容器内。

这里有一个演示 (尝试重新调整窗口的大小)

 var visibleY = function(el){ var top = el.getBoundingClientRect().top, rect, el = el.parentNode; do { rect = el.getBoundingClientRect(); if (top <= rect.bottom === false) return false; el = el.parentNode; } while (el != document.body); // Check its within the document viewport return top <= document.documentElement.clientHeight; }; 

我只需要检查它是否在Y轴上可见(对于滚动ajax加载更多的loggingfunction)。

更好的解决scheme:

 function getViewportSize(w) { var w = w || window; if(w.innerWidth != null) return {w:w.innerWidth, h:w.innerHeight}; var d = w.document; if (document.compatMode == "CSS1Compat") { return { w: d.documentElement.clientWidth, h: d.documentElement.clientHeight }; } return { w: d.body.clientWidth, h: d.body.clientWidth }; } function isViewportVisible(e) { var box = e.getBoundingClientRect(); var height = box.height || (box.bottom - box.top); var width = box.width || (box.right - box.left); var viewport = getViewportSize(); if(!height || !width) return false; if(box.top > viewport.h || box.bottom < 0) return false; if(box.right < 0 || box.left > viewport.w) return false; return true; } 

检查元素是否至less部分在视图中(垂直尺寸):

 function inView(element) { var box = element.getBoundingClientRect(); return inViewBox(box); } function inViewBox(box) { return ((box.bottom < 0) || (box.top > getWindowSize().h)) ? false : true; } function getWindowSize() { return { w: document.body.offsetWidth || document.documentElement.offsetWidth || window.innerWidth, h: document.body.offsetHeight || document.documentElement.offsetHeight || window.innerHeight} } 

我有同样的问题,并通过使用getBoundingClientRect()计算出来。 这个代码是完全“通用的”,只需要编写一次就可以工作(你不必为每个你想知道的元素在视口中写出)。 此代码只检查是否在视口中垂直不水平 。 在这种情况下,variables(数组)“元素”将视图中垂直检查的所有元素保存在视口中,因此可以抓取任何您想要的元素并将其存储在此处。 'for循环'遍历每个元素,并检查它是否在视口中是垂直的。 这个代码每次用户滚动执行! 如果getBoudingClientRect()。top小于3/4视口(该元素是视口中的四分之一),它将在“视口”中注册。 由于代码是通用的,您将需要知道“哪个”元素在视口中。 要发现这一点,你可以通过自定义属性,节点名称,ID,类名等等来确定它。 这里是我的代码(告诉我,如果它不工作,它已经在IE 11,FireFox 40.0.3,Chrome版本45.0.2454.85米,Opera 31.0.1889.174和边缘与Windows 10,[非Safari] )…

 //scrolling handlers... window.onscroll = function(){ var elements = document.getElementById('whatever').getElementsByClassName('whatever'); for(var i = 0; i != elements.length; i++) { if(elements[i].getBoundingClientRect().top <= window.innerHeight*0.75 && elements[i].getBoundingClientRect().top > 0) { console.log(elements[i].nodeName + ' ' + elements[i].className + ' ' + elements[i].id + ' is in the viewport; proceed with whatever code you want to do here.'); } }; 

希望这有助于某人:-)

为我工作的简单而小巧的解决scheme。

示例您想要查看元素是否在具有溢出滚动的父元素中可见。

 $(window).on('scroll', function () { var container = $('#sidebar'); var containerHeight = container.height(); var scrollPosition = $('#row1).offset().top - container.offset().top; if (containerHeight < scrollPosition) { console.log('not visible'); } else { console.log('visible'); } } 

我使用这个函数(它只会检查y是否被屏蔽,因为大部分时间x不是必需的)

 function elementInViewport(el) { var elinfo = { "top":el.offsetTop, "height":el.offsetHeight, }; if (elinfo.top + elinfo.height < window.pageYOffset || elinfo.top > window.pageYOffset + window.innerHeight) { return false; } else { return true; } } 

对于一个类似的挑战,我真的很喜欢这个为scrollIntoViewIfNeeded()公开一个polyfill的 要点 。

所有必要的功夫需要回答在这个区块内:

 var parent = this.parentNode, parentComputedStyle = window.getComputedStyle(parent, null), parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')), parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')), overTop = this.offsetTop - parent.offsetTop < parent.scrollTop, overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight), overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft, overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth), alignWithTop = overTop && !overBottom; 

this是指你想知道的元素,如果它是overTopoverBottom – 只是应该得到漂移…

我想要一个简单的jQuery解决scheme(只检查垂直滚动),所以我修改了Adam Rehals的代码。 此示例单击视口中的所有button,每秒检查5次。 (button点击时button被禁用)

 $(function () { var loadButtons = $('.btn-load-more'); function clickButtonsIfInViewport() { loadButtons.each(function () { var element = $(this); var elementOffset = element.offset(); var elementTop = elementOffset.top; var elementBottom = elementOffset.top + element.outerHeight(true); var windowTop = $window.scrollTop(); var windowBottom = windowTop + $window.height(); if (windowTop > elementBottom || windowBottom < elementTop) { return; } element.click(); }); } setInterval(clickButtonsIfInViewport, 200); });