7

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>

JSFIDDLE

arjuncc
  • 3,227
  • 5
  • 42
  • 77
  • Why do you have a height set on the parent, along with overflow: hidden, if you want the children to be visible? It's not really clear what you are doing here. – ralph.m May 10 '13 at 13:13
  • @ralph.m, I am building a slider. An I need to know the non visible divs. – arjuncc May 10 '13 at 13:14
  • Do you want to display all the `.childDivStyle` that are not visible or simply show one at a time (think of a sprite image)? – Marc Audet May 10 '13 at 13:15
  • why not use a ready made one - there are millions of free ones out there – Pete May 10 '13 at 13:15
  • @MarcAudet no, I want to just identify the non visible ones – arjuncc May 10 '13 at 13:17
  • @Pete, sorry to say this sir, but am not really allowed to use any external library. – arjuncc May 10 '13 at 13:18
  • jquery is an external library? – Pete May 10 '13 at 13:18
  • @arjuncc have a look at jCarouselLite, http://gmarwaha.com/jquery/jcarousellite/, even if you're not allowed to use it, you could rip it off without remorse. – Andreas Eriksson May 10 '13 at 13:19
  • @Pete, Sir, we have special permission for certain libraries, which are trusted by the client. – arjuncc May 10 '13 at 13:19
  • In your fiddle, div-1 and div-2 are visible by design, so you want to shift the list over so div-2 and div-3, then div-3 and div-4 are visible? – Marc Audet May 10 '13 at 13:20
  • @MarcAudet . Sorry to say. Am not the decision maker. :( . Its a task assigned :( – arjuncc May 10 '13 at 13:21
  • @MarcAudet Yea, I need that divs which are not visible in the view port. – arjuncc May 10 '13 at 13:22
  • So, ideally, you want some type of a selector that would return, in your example, div-3, div-4 and div-5, maybe as a jQuery object? – Marc Audet May 10 '13 at 13:23
  • @MarcAudet, selector or a java script method comparing the positions. – arjuncc May 10 '13 at 13:27
  • not sure what you need to check the visibility for but if you need a slider without using an external library I would make it like this: http://jsfiddle.net/5nW53/. if you are wanting to continue down the finding if a div is visible or not, this may help: http://stackoverflow.com/questions/7668636/check-with-jquery-if-div-has-overflowing-elements – Pete May 10 '13 at 13:44

6 Answers6

3

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.

conca
  • 1,394
  • 9
  • 10
  • Nice answer, but I have to consider even if it is aligned rightwise or left wise. am adding +1 – arjuncc May 10 '13 at 13:24
  • This is not fool proof since it depends on the precise geometry of the layout. For example, if you set the black border with to 0px, then you get different results. However, the idea is good but the implementation demands precision. – Marc Audet May 10 '13 at 13:28
  • I would recommend using a combination of [outerWidth(true)](http://api.jquery.com/outerWidth/) and [outerHeight(true)](http://api.jquery.com/outerHeight/) so that the padding, border, and margins are included in dimension calculations as well. – Zhihao May 10 '13 at 13:31
  • You can use $(div).position().left, $(div).width() and $('#parent').width() to test for right and left align – conca May 10 '13 at 13:32
1

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/

vijay
  • 1,323
  • 1
  • 11
  • 15
  • This seems to work well. I tweaked the HTML, for example, set border to 0px, vary the width of `.parentDivStyle` and the true/false value was accurate. This looks pretty robust. Please explain `this.offsetTop`, thank-you. – Marc Audet May 10 '13 at 13:38
  • 1
    it will return the distance of the current child element relative to the top of the parent node. http://help.dottoro.com/ljnvukbb.php – vijay May 10 '13 at 13:46
1

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

http://jsfiddle.net/arpTx/18/

$("#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); }
Jason
  • 15,915
  • 3
  • 48
  • 72
1

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.

Xotic750
  • 22,914
  • 8
  • 57
  • 79
1

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

Community
  • 1
  • 1
Indigenuity
  • 9,332
  • 6
  • 39
  • 68
-1

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
    }
}
Anickyan
  • 404
  • 2
  • 10
  • 3
    This does not quite work as you might expect since all the `.childDivStyle` elements are visible, which is different from being hidden because of the overflow property setting. See http://jsfiddle.net/audetwebdesign/3suDz/5/ – Marc Audet May 10 '13 at 13:34