Reputation: 3287
I have a div(parentDivStyle) with position absolute
which is my parent div. Then I have 5 children(childDivStyle) div inside the parent div with position relative
. I have set the overflow
to hidden of the parent div. So some of the child divs are not visible. I would like to get the divs which are not visible by jquery. Is there any way?
I have googled it and most of the results where related to "visible" property, That is not what I want. And also I am not preferring any plugin. Any help please.
CSS
.parentDivStyle {
overflow:hidden;
width:300px;
height:50px;
position:absolute;
background:#ccc;
float:left;
}
.childDivStyle {
width:100px;
height:50px;
position:relative;
float:left;
background:red;
border: 1px solid black;
}
HTML
<div class="parentDivStyle">
<div class="childDivStyle">1</div>
<div class="childDivStyle">2</div>
<div class="childDivStyle">3</div>
<div class="childDivStyle">4</div>
<div class="childDivStyle">5</div>
</div>
Upvotes: 7
Views: 605
Reputation: 9740
Using this answer about getting coordinates of elements, you can figure out where elements are in respect to each other. Once you know the coordinates of the visible area, you can easily figure out what child elements are visible.
This will tell you whether the elements are visible, and if not, which direction they are with respects to the container.
displayCoords = function(element) {
var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);
var childElements = element.children;
for(i = 0; i < childElements.length; i++)
{
childRect = childElements[i].getBoundingClientRect();
console.log(childRect.top, childRect.right, childRect.bottom, childRect.left);
if(childRect.top >= rect.bottom)
console.log("not visible -- off the bottom of element");
else if(childRect.left >= rect.right)
console.log("not visible -- off the right of element");
else if(childRect.bottom <= rect.top)
console.log("not visible -- off the top of element");
else if(childRect.right <= rect.left)
console.log("not visible -- off the left of element");
}
}
I forked your JSFiddle here
Upvotes: 1
Reputation: 23482
How about this as a solution
CSS
.parentDivStyle {
overflow:hidden;
width:300px;
height:50px;
position:absolute;
background:#ccc;
float:left;
}
.childDivStyle {
width:100px;
height:50px;
position:relative;
float:left;
background:red;
border: 1px solid black;
}
HTML
<div id="parent" class="parentDivStyle">
<div class="childDivStyle">1</div>
<div class="childDivStyle">2</div>
<div class="childDivStyle">3</div>
<div class="childDivStyle">4</div>
<div class="childDivStyle">5</div>
</div>
Javascript
function getNotVisible(parentId, childClassName) {
var parent = document.getElementById(parentId),
children,
elements;
if (parent) {
children = parent.getElementsByClassName(childClassName);
if (children) {
elements = [];
Array.prototype.forEach.call(children, function (child) {
var pBounds = parent.getBoundingClientRect(),
cBounds = child.getBoundingClientRect();
if (cBounds.right < pBounds.left || cBounds.left > pBounds.right || cBounds.bottom < pBounds.top || cBounds.top > pBounds.bottom) {
elements.push(child);
}
});
}
}
return elements;
}
console.log(getNotVisible("parent", "childDivStyle"));
On jsfiddle
BTW, if you want a jquery object from this then do the following
var $hiddens = $(getNotVisible("parent", "childDivStyle"));
Also, if you want an array returned rather than undefined, i.e. silently fail if the parent element is not or no children are found.
Then delete
elements = [];
And change
var parent = document.getElementById(parentId),
children,
elements = [];
And of course this all depends on you setting your CSS correctly, as no checks are being made for visibility
or overflow
, etc.
If you want to add CSS checks, to double check your CSS work, then you can use window.getComputedStyle and check the important values.
Upvotes: 1
Reputation: 15931
Here's a fiddle that takes into account the relative nature of the child divs. It can be condensed, but I left it in long-form so the logic is apparent
$("#p").children().each(
function(idx, el) {
var pos = $(el).position();
console.log("child " + $(el).text() + " is visible: " + isVisible(pos.left, pos.top));
});
function isVisible(x, y) {
var pos = $("#p").position();
var left = pos.left;
var right = left + $("#p").width();
var top = pos.top;
var bottom = top + $("#p").height();
x += left;
y += top;
return (x >= left && x < right) && (y >= top && y < bottom); }
Upvotes: 1
Reputation: 1353
Try below code
$('div.parentDivStyle div').each(function(index, element){
alert(this.offsetTop + $(this).height() > $('div.parentDivStyle').height());
});
if child div is hidden then it will return true else false.
Check on fiddle http://jsfiddle.net/3suDz/4/
Upvotes: 1
Reputation: 414
You can use jQuery's is() function, like so:
$(element).is(":visible")
So in your case, you would do something like this:
var elems = $(".childDivStyle");
for(var i = 0; i < elems.length; i++)
{
if(!($(elems[i]).is(":visible")))
{
// The element is hidden
}
}
Upvotes: -1
Reputation: 1434
You can use the position of the child divs, and the height of the parent like this:
$('#parent .childDivStyle').each(function(index,div){
if($(div).position().top > $('#parent').height()) alert($(div).html())
});
The working fiddle: http://jsfiddle.net/3suDz/3/
Hope it helps.
Upvotes: 3