Reputation: 2681
I'm trying to check to make sure an item is visible before I start working on it using the following function
isVisible: function (node, doc, x, y) {
var el = doc.elementFromPoint(x, y);
if (node === el) return true;
else return false;
},
x
and y
are positions of the selected node and is calculated by
findPos: function (node) {
var pos = new Object();
pos.left = pos.top = 0;
if (node.offsetParent) {
do {
pos.left += node.offsetLeft;
pos.top += node.offsetTop;
} while (node = node.offsetParent);
}
return pos;
}
Everything works fine. However, when I scroll the page down, the isVisible
function is no longer returning the right value. This is caused by the position having changed but the find position function not returning the right value.
Is there a method to get the position of an element like the reverse of elementFromPoint
? Or does anyone have another method?
Upvotes: 0
Views: 991
Reputation: 1770
I just wrote an isVisible()
method that uses the elementFromPoint()
method and should work in IE9+ to detect if an element is visible.
var isVisible = function(elem) {
var w = window, d = document, height, rects, on_top;
if(!elem || (elem && elem.nodeType !== 1) || !elem.getClientRects || !d.elementFromPoint || !d.querySelector || !elem.contains) {
return false;
}
if (elem.offsetWidth === 0 || elem.offsetHeight === 0) {
return false;
}
height = w.innerHeight ? w.innerHeight: d.documentElement.clientHeight;
rects = elem.getClientRects();
on_top = function(r, elem) {
var x = (r.left + r.right)/2,
y = (r.top + r.bottom)/2,
elemFromPoint = d.elementFromPoint(x, y);
return (elemFromPoint === elem || elem.contains(elemFromPoint));
};
for (var i = 0, l = rects.length; i < l; i++) {
var r = rects[i],
in_viewport = r.top > 0 ? r.top <= height : (r.bottom > 0 && r.bottom <= height);
if (in_viewport && on_top(r, elem)) {
return true;
}
}
return false;
};
You would call it like this: isVisible(document.getElementById('at-follow'));
Also, here is the gist of it.
Upvotes: 2
Reputation: 2681
I was able to fix this by adding window.scrollX
and window.scrollY
to the doc.elementFromPoint()
input parameters x
and y
isVisible: function (node, doc, x, y)
{
var el = doc.elementFromPoint(x-window.scrollX, y-window.scrollY);
if (node === el) return true;
else return false;
},
this seems to work fine
Upvotes: 1
Reputation: 4423
This library should be what you're looking for: https://github.com/cpatik/within-viewport/blob/master/withinViewport.js
Upvotes: 0