I'm using the following function to check if an element is visible or not in the viewport :
function elementInViewport(el) {
let top = el.offsetTop;
let left = el.offsetLeft;
const width = el.offsetWidth;
const 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
);
}
However, I want to check if an element is 50%
visible in the viewport. So if half of it is only showing, the check should return true
. I know this is possible using the Intersection Observer API, however that is not an option for me as I want this to be compatible with IE11
.
So even if it's a part of a element but it covers the full height of the screen, it should be 100% in viewport.
If an element is in the viewport, it's position from the top and left will always be greater than or equal to 0 . It's distance from the right will be less than or equal to the total width of the viewport, and it's distance from the bottom will be less than or equal to the height of the viewport.
To know whether the element is fully visible in viewport, you will need to check whether top >= 0, and bottom is less than the screen height. In a similar way you can also check for partial visibility, top is less than screen height and bottom >= 0.
This test will work for one direction (either horizontal or vertical).
function checkFifty(el) {
var rect = el.getBoundingClientRect();
return (
rect.top + (rect.height/2) > 0 && // top
rect.left + (rect.width/2) > 0 && // left
rect.top + (rect.height/2) < (window.innerHeight || document.documentElement.clientHeight) && // bottom
rect.left + (rect.width/2) < (window.innerWidth || document.documentElement.clientWidth) // right
);
}
Note that the code that you copied to your question is not a good solution as it is very slow (and inaccurate). You should use getBoundingClientRect
and you are done without any "manual" DOM traversal.
You can play around with this to see it in action:
function checkFifty() {
var el = document.getElementById("element");
var rect = el.getBoundingClientRect();
console.log (
// top
rect.top + (rect.height/2) > 0 &&
// left
rect.left + (rect.width/2) > 0 &&
// bottom
rect.top + (rect.height/2) < (window.innerHeight || document.documentElement.clientHeight) &&
// right
rect.left + (rect.width/2) < (window.innerWidth || document.documentElement.clientWidth)
);
}
function showCoordinates() {
var el = document.getElementById("element");
var rect = el.getBoundingClientRect();
console.log(rect);
}
#buttons {
position: fixed;
top: 0px;
left: 0px;
}
#container {
width: 2000px;
height: 2000px;
}
#element {
margin: 800px;
width: 200px;
height: 200px;
background-color: red;
}
<div id="buttons">
<button onclick="showCoordinates()">coords</button>
<button onclick="checkFifty()">check 50%</button>
<p>scroll to the box and press the buttons. check the console output.</p>
</div>
<div id="container">
<div id="element"></div>
</div>
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