Skip to content

Instantly share code, notes, and snippets.

@m3g4p0p
Last active July 21, 2016 22:59
Show Gist options
  • Save m3g4p0p/f221f63e36a7a56d2deb75bbf086a0db to your computer and use it in GitHub Desktop.
Save m3g4p0p/f221f63e36a7a56d2deb75bbf086a0db to your computer and use it in GitHub Desktop.
jQuery plugin to reduce the set of elements to those being within the viewport
/**
* Plugin to reduce a set of elements to those
* visible in the viewport
*
* @param {Object}
* @param {Function}
* @param {Function}
* @return {jQuery}
*/
(function($) {
$.fn.viewport = function(options, callback1, callback2) {
'use strict';
var defaults = {
horizontal: true,
vertical : true,
enter : 0
},
$window = $(window),
windowScrollTop = $window.scrollTop(),
windowScrollLeft = $window.scrollLeft(),
windowHeight = $window.height(),
windowWidth = $window.width();
/**
* Check for the visibility by comparing
* size and position against the viewport
*
* @param {Integer}
* @param {Integer}
* @param {Integer}
* @param {Integer}
* @return {Boolean}
*/
var _isVisible = function(
elementPosition,
elementSize,
windowPosition,
windowSize
) {
return elementPosition + (elementSize * options.enter)
< windowPosition + windowSize &&
elementPosition + elementSize >
windowPosition + (elementSize * options.enter);
};
/**
* Method to filter the set of elements
*
* @return {Boolean}
*/
var _filter = function() {
var $this = $(this),
thisOffset = $this.offset(),
isVisible = true;
// Check vertical visibility
if (options.vertical) {
isVisible = isVisible && _isVisible(
thisOffset.top,
$this.outerHeight(),
windowScrollTop,
windowHeight
);
}
// Check horizontal visibility
if (options.horizontal) {
isVisible = isVisible && _isVisible(
thisOffset.left,
$this.outerWidth(),
windowScrollLeft,
windowWidth
);
}
try {
if (callback1 && isVisible) {
callback1.call(this);
} else if (callback2 && !isVisible) {
callback2.call(this);
}
} catch (err) {
console.error(err)
}
return isVisible;
};
/**
* Handle the arguments
*/
if (options && typeof options === 'object') {
options = $.extend({}, defaults, options);
} else {
callback2 = callback1;
callback1 = options;
options = defaults;
}
return this.filter(_filter);
};
})(window.jQuery);
(function($){$.fn.viewport=function(options,callback1,callback2){'use strict';var defaults={horizontal:true,vertical:true,enter:0},$window=$(window),windowScrollTop=$window.scrollTop(),windowScrollLeft=$window.scrollLeft(),windowHeight=$window.height(),windowWidth=$window.width();var _isVisible=function(elementPosition,elementSize,windowPosition,windowSize){return elementPosition+(elementSize*options.enter)<windowPosition+windowSize&&elementPosition+elementSize>windowPosition+(elementSize*options.enter)};var _filter=function(){var $this=$(this),thisOffset=$this.offset(),isVisible=true;if(options.vertical){isVisible=isVisible&&_isVisible(thisOffset.top,$this.outerHeight(),windowScrollTop,windowHeight)}if(options.horizontal){isVisible=isVisible&&_isVisible(thisOffset.left,$this.outerWidth(),windowScrollLeft,windowWidth)}try{if(callback1&&isVisible){callback1.call(this)}else if(callback2&&!isVisible){callback2.call(this)}}catch(err){console.error(err)}return isVisible};if(options&&typeof options==='object'){options=$.extend({},defaults,options)}else{callback2=callback1;callback1=options;options=defaults}return this.filter(_filter)}})(window.jQuery);
@m3g4p0p
Copy link
Author

m3g4p0p commented Jun 21, 2016

jQuery-viewport

Reduces the set of matched elements to those which are visible in the viewport.

Usage

.viewport(options, callback, callback)

The function takes three optional arguments:

  • An options object holding the properties vertical and horizontal to specify if the vertical and horizontal visibility respectively should be checked (both default to true), as well as the property enter which specifies how much of the element must be visible for the filter to apply (e.g. enter: 1 means that it has to be fully within the viewport; defaults to 0, which means that it is matched as soon as a single pixel enters the viewport).
  • A callback function which gets called on the matched elements which are within the viewport.
  • A second callback function which gets called on those elements being not within the viewport. If you only want to provide this second callback function, the first one has to be null. This might be useful as other jQuery methods (such as adding a class) can be called on the matched elements directly.

Example

$(window).scroll(function() {
    $('div').viewport(null, function() {
        $(this).removeClass('foo');
    }).addClass('foo');
});

Demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment