How to get on-screen visible element objects in jQuery?

30,538

First of all on-screen visible area is known as Viewport.

image is took from OP and cleaned up in Photoshop

(image is taken from OP. Cleared and edited in Photoshop)


So all you need is to detect all elements in your Viewport.

This can be achieved using many plugins for jQuery, but I'll explain you on one example, which is called as jQuery withinviewport

Link to source and documentation on: [ withInViewport - Github ]


Step 1:

Download plugins and include jQuery framework and withinviewport plugin in your script:

<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
<script src="withinViewport.js"></script>
<script src="jquery.withinviewport.js"></script>

.

Step 2:

Initialise function on scroll event:

$(window).bind("scroll", function() {
    //your code placeholder
});

.

Step 3:

Use withinviewport selector to get all elements in you Viewport and by each element add class to corresponding list-item in your #timeline container:

$("#elements > div").withinviewport().each(function() {
   $('#timeline > li[view-id="'+$(this)[0].id+'"]').addClass('active');
});

Step 4:

Put all together:

$(window).bind("scroll", function() {

    //clear all active class
    $('#timeline > li').removeClass('active');

    //add active class to timeline
    $("#elements > div").withinviewport().each(function() {
         $('#timeline > li[view-id="'+$(this)[0].id+'"]').addClass('active');
    });
});

.


.

Also this plugin gives you opportunity to set top, bottom, left and right offset for view-port.

See demo here: http://patik.com/code/within-viewport/

Share:
30,538
Admin
Author by

Admin

Updated on October 20, 2020

Comments

  • Admin
    Admin over 3 years

    I have a list of objects in DOM, which is longer than screen height area.

    I need to detect on-screen visible objects only to make something like timeline tree-view. (something like on the picture below):

    enter image description here

    My DOM looks like this:

    <!-- elements visibility on screen to be DETECTED -->
    <div id="elements">
        <div id="elem-1">Lorem ipsum</div>
        <div id="elem-2">Lorem ipsum</div>
        <div id="elem-3">Lorem ipsum</div>
        <div id="elem-4">Lorem ipsum</div>
        <div id="elem-5">Lorem ipsum</div>
        <div id="elem-6">Lorem ipsum</div>
        <div id="elem-7">Lorem ipsum</div>
        <div id="elem-8">Lorem ipsum</div>
    </div>
    
    
    <!--elements visibility on screen to be AFFECTED  -->
    <ul id="timeline">
        <li view-id="elem-1">Elem-1</li>
        <li view-id="elem-2">Elem-2</li>
        <li view-id="elem-3" class="active">Elem-3</li>
        <li view-id="elem-4" class="active">Elem-4</li>
        <li view-id="elem-5" class="active">Elem-5</li>
        <li view-id="elem-6" class="active">Elem-6</li>
        <li view-id="elem-7">Elem-7</li>
        <li view-id="elem-8">Elem-8</li>
    </ul>
    

    My goal is to detect IDs' of on-screen visible elements from #elements container and assign active class to corresponding elements in #timeline container.

    I need to do this process on Scroll event.

    Any ideas how to achieve this?

  • Jamie Hutber
    Jamie Hutber over 10 years
    Please explain the difference between 'doing it' and using a plugin? I'd love to know. Also please show me where the OP has said I don't want to use a plugin
  • zur4ik
    zur4ik over 10 years
    @Zap7 actually this is the way wow to do it. I don't see the reason why it was downvoted.
  • Jamie Hutber
    Jamie Hutber over 10 years
    I've upvoted this answer... even though its the same as mine
  • Brian
    Brian over 10 years
    @Zap7 Overzealous pedantry. If you were to insist "doing it", we could have linked to the exact line in the source, but that isn't particularly helpful to anyone.
  • Jamie Hutber
    Jamie Hutber over 10 years
    @Brian this is the exact reason i've voted for the question to be closed.
  • zur4ik
    zur4ik over 10 years
    @musefan I had same answer on different forum and just copied most part. Only I took picture of Punto and quickly cleaned up in photoshop.
  • Frédéric Hamidi
    Frédéric Hamidi over 10 years
    @zur4ik, to be perfectly clear: Punto has only asked two questions so far and you answered both (and your answers were accepted). The only answer he provided was to one of your questions, and you accepted it. Coincidences happen, but this looks a little too much.
  • Billy Chan
    Billy Chan over 10 years
    I don't think there is anything wrong with using plugin. Even if you wrote the code by your own, it's better to extract this feature into a plugin later. So why re-invent wheel? However, I agree with @musefan's point that the answer is way too quick to type.
  • zur4ik
    zur4ik over 10 years
    @FrédéricHamidi looks like you are right. I just looked on it.
  • Jamie Hutber
    Jamie Hutber over 10 years
    lol I must say I did think blimey! that was one hella quick reply with a whole lot of content.
  • Admin
    Admin over 10 years
    @zur4ik this is exactly what i was searching for. Thanks for the best answer. This is another time you are my help! Thank you!
  • musefan
    musefan over 10 years
    @zur4ik: Look, just be honest, you and the OP (assuming you are not both accounts) decided to get together and make this post. I personally have no problem with answering your "own questions", and having this as a point of reference isn't a problem either because it could be helpful to other visitors. The thing I am debating though is that it is a duplicate and I don't think this question deserves to exist for that reason (it also doesn't show any effort to solve the problem prior to asking)
  • zur4ik
    zur4ik over 10 years
    I don't understand whats wrong. I had same content and it was just matter of Copy/Paste. I just modified picture in Photoshop. I don't think that it's not possible to answer in 3 mins with big content.
  • Justin01
    Justin01 over 8 years
    This is old, but I thought I'd specify something, because I did the mistake of copy/pasting @zur4ik's code; the function is "withinviewport" (lowercase "V"), and not "withinViewport" with a capital V like he wrote it. That is all.
  • zur4ik
    zur4ik over 8 years
    @Justin01 Thanks for note. Updated.