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

JavascriptJqueryHtmlCssDom

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

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/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2893747View Question on Stackoverflow
Solution 1 - Javascriptzur4ikView Answer on Stackoverflow