- protonet/jquery.inview adds detection by adding events for in/out. You don't need to initialize any plugin which also means you can't pass any per element configuration arguments.
- Several different scrolling animation libraries: github/litera, github/balupton, and github/flesler. These don't detect the position - they change it.
- A specific use of scroll position detection is Paul Irish's Infinite Scroll plugin.
- Use the Scrollbar as a Animation Play Head - Superscrollorama leverages the GreenSock Animation Platform to really enhance content presentation and navigation. Not really either detect or positioning - I just thought it was cool.
I'm sure others exist but I thought it was an interesting problem to explore so I set out to build a basic solution that would have the following functionality:
- Add elements of interest to some global list with configuration options
- Listen to the window scroll event and check each element to see if its in the viewport
- When it first enters/leaves trigger an event/callback to allow further processing
Register ElementsFirst, we need to be able to register the elements we care about so their scroll position can be monitored. We'll use this global list in the scroll event handler later:
This just creates a tracking object which contains state, options, and the target element.
Monitor ScrollingThe next step is to listen for scroll events on the window. We can't listen to the individual items since they won't generate scroll events - the container that scrolls will emit these which means we need to listen to that container element and then check all the registered items to determine if they scrolled in or out of the visible part of the page. However, scrolling can generate a lot of events and probably will cause a performance hit if we are constantly trying to test for the position of all the registered elements. What we need is a way to only process one event per some interval of time. A possible solution is the Underscore throttle function which is a nice way to manage events that may rapidly fire to help boost performance in a situation where it might degrade if the underlying logic ran that frequently. Now, I didn't want a dependency on Underscore in this case so I just implemented a simple version specific to my needs:
Another benefit of this buffer is if the user scrolls quickly past an item, it won't be detected as being in the view.
Check and Fire EventsThe
checkInView()function referenced above iterates over all the registered elements we're interested in and checks the boundaries of the element against the visible part of the page. When the element was registered, an object was created with a
invpkey to track the state of the element. False means its not in the visible part of the screen and true means it is. This allows us to track when it changes and to fire the appropriate event:
Create a PluginAt this point, we have the three parts required to enable the detection and trigger an event. Now, we just need to package it up so its easier to use with jQuery. For testing, I made a quick plugin:
This plugin is lacking the necessary cleanup handling and some other housekeeping but will work well enough for now. Next, we can create some markup:
And use the plugin to monitor the DIVs as they are scrolled:
I dropped this code into jsFiddle as a demo. You'll need to have your console open to see the output.
Next StepsAt this point, this is only a proof-of-concept to hash out the required functionality for a more robust version. Its missing some critical elements:
- Only detects scrolling up and down not left and right
- Only can detect elements scrolling in the window, not elements contained inside another element that scrolls
- The jQuery plugin is lacking teardown logic required to stop monitoring an element and free up memory