The jQuery ‚inview‘ Plugin

Von Protonet Team. Veröffentlicht 29. Dezember 2010.

A couple of months ago, we needed a way to detect whether an element is visible to the user. The use case behind this was that we wanted to implement an endless scrolling mechanism for the Protonet dashboard timeline: If the user reaches the last message in the timeline more messages had to be loaded without the user clicking anywhere. You might have seen such thing in the new twitter web site.

Thanks to Google, we stumbled upon this blog post written by Remy Sharp. There he shows off something that was exactly what we were searching for: A bindable event for jQuery which gets triggered as soon as the element appears in the browser’s viewport. The plugin was very suitable in the beginning.

Broadening it’s usage, we noticed that a few essential things were missing

  • The plugin only honored vertical not horizontal coordinates – it was even triggered when the observed element was on the outer right or left of the viewport. The plugin used the browser’s window.onscroll event to check whether an element is visible. The problem here is that elements also can come into view without the user performing a scroll. For instance an element could appear in the user’s view through an effect or by manipulating the DOM (e.g. removing/hiding elements before the observed element).
  • Elements within overflow: scroll; containers weren’t respected – scrolling in such doesn’t fire the window.onscroll event.
  • When using jQuery’s mighty live/delegate methods, the inview event wasn’t working at all.

Also we discovered a few bugs

  • One for example was that the event was triggered on elements that weren’t in the dom tree.
  • Another issue was that it didn’t seem to work correctly in Mobile Safari on iOS (iPad, iPhone) versions.

Luckily someone already brought the code to GitHub. Starting a hardcore forking action and implementing and fixing the above mentioned issues was the obvious thing to do.

So here we are, introducing: rebrushed and lightweight …

Browser Support

The plugin is compatible with the following browsers we tested:

  • Firefox 3+
  • Safari 3+
  • Chrome 7+
  • Opera 10+
  • IE 6+
  • Mobile Safari on iPad 4.2.2
  • Fennec 4b on Android 2.2
  • Opera Mobile 10.1b on Android 2.2
  • Mobile WebKit on Android 2.2

Usage

1) Simple Example

$("#foobar").bind("inview", function(isVisible) {
  // Event is triggered once the element becomes visible in the browser's viewport, and once when it becomes invisible
  if (isVisible) {
    console.log("element #foobar became visible in the browser's viewport");
  } else {
    console.log("element #foobar became invisible in the browser's viewport");
  }
});

2) Lazyloading

Wait to load images until they appear in the viewport.

  • Increases the overall page performance due to less data being processed simultaneously
  • Reduces the amount of HTTP requests, yslow, yada yada, just to name a few
$('img[data-src]').live('inview', function(event, isVisible) {
  if (!isVisible) { return; }

  var img = $(this);
  img
    .css('opacity', 0)
    // Show a smooth animation when the image is loaded
    .load(function() { img.animate({ opacity: 1 }, 500); })
    // Change src
    .attr('src', img.attr('data-src'))
    // Remove it from matching set of elements of live event selector
    .removeAttr('data-src');
});

Ever thought of building an Office Air Quality Indicator
or a Voice Based Cooking Timer yourself in just minutes?

Protonet’s Experimental Platform Is Here

Further Links