Possible Duplicate:
jQuery - Check if element is visible after scroling
I'm trying to determine if an element is visible on screen. In order to to this, I'm trying to find the element's vertical position using offsetTop, but the value returned is not correct. In this case, the element is not visible unless you scroll down. But despite of this, offsetTop returns a value of 618 when my screen height is 703, so according to offsetTop the element should be visible.
The code I'm using looks like this:
function posY(obj) { var curtop = 0; if( obj.offsetParent ) { while(1) { curtop += obj.offsetTop; if( !obj.offsetParent ) { break; } obj = obj.offsetParent; } } else if( obj.y ) { curtop += obj.y; } return curtop; }
Thank you in advance!
Use the getBoundingClientRect() method to get the size of the element and its relative position to the viewport. Compare the position of the element with the viewport height and width to check if the element is visible in the viewport or not.
In JavaScript, the quickest way to check if an element is hidden or visible in DOM is to use the getComputedStyle() method. This method returns the actual values of CSS properties used to render an HTML element in DOM. An HTML element can be hidden due to either display:none or visibility:hidden CSS properties.
Answer: Use the jQuery :visible Selector You can use the jQuery :visible selector to check whether an element is visible in the layout or not. This selector will also select the elements with visibility: hidden; or opacity: 0; , because they preserve space in the layout even they are not visible to the eye.
--- Shameless plug ---
I have added this function to a library I created vanillajs-browser-helpers: https://github.com/Tokimon/vanillajs-browser-helpers/blob/master/inView.js
-------------------------------
Well BenM stated, you need to detect the height of the viewport + the scroll position to match up with your top position. The function you are using is ok and does the job, though its a bit more complex than it needs to be.
If you don't use jQuery
then the script would be something like this:
function posY(elm) { var test = elm, top = 0; while(!!test && test.tagName.toLowerCase() !== "body") { top += test.offsetTop; test = test.offsetParent; } return top; } function viewPortHeight() { var de = document.documentElement; if(!!window.innerWidth) { return window.innerHeight; } else if( de && !isNaN(de.clientHeight) ) { return de.clientHeight; } return 0; } function scrollY() { if( window.pageYOffset ) { return window.pageYOffset; } return Math.max(document.documentElement.scrollTop, document.body.scrollTop); } function checkvisible( elm ) { var vpH = viewPortHeight(), // Viewport Height st = scrollY(), // Scroll Top y = posY(elm); return (y > (vpH + st)); }
Using jQuery is a lot easier:
function checkVisible( elm, evalType ) { evalType = evalType || "visible"; var vpH = $(window).height(), // Viewport Height st = $(window).scrollTop(), // Scroll Top y = $(elm).offset().top, elementHeight = $(elm).height(); if (evalType === "visible") return ((y < (vpH + st)) && (y > (st - elementHeight))); if (evalType === "above") return ((y < (vpH + st))); }
This even offers a second parameter. With "visible" (or no second parameter) it strictly checks whether an element is on screen. If it is set to "above" it will return true when the element in question is on or above the screen.
See in action: http://jsfiddle.net/RJX5N/2/
I hope this answers your question.
-- IMPROVED VERSION--
This is a lot shorter and should do it as well:
function checkVisible(elm) { var rect = elm.getBoundingClientRect(); var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight); return !(rect.bottom < 0 || rect.top - viewHeight >= 0); }
with a fiddle to prove it: http://jsfiddle.net/t2L274ty/1/
And a version with threshold
and mode
included:
function checkVisible(elm, threshold, mode) { threshold = threshold || 0; mode = mode || 'visible'; var rect = elm.getBoundingClientRect(); var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight); var above = rect.bottom - threshold < 0; var below = rect.top - viewHeight + threshold >= 0; return mode === 'above' ? above : (mode === 'below' ? below : !above && !below); }
and with a fiddle to prove it: http://jsfiddle.net/t2L274ty/2/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With