Skip to content
This repository was archived by the owner on May 14, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
0.3.7 allow binding on different viewports apart from window
0.3.3 IE8 compatibility fix.
0.3.2 Code cleanups. Appear now supports not only jQuery selectors but also raw DOM nodes wrapped in jQuery.
0.3.1 Added "disappear" event. Removed first argument (callback function) from $.fn.appear function. "appear" event is now triggered for each appeared element (before it was triggered only for a first element in selector).
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ This plugin can be used to prevent unnecessary processeing for content that is h

It implements a custom *appear*/*disappear* events which are fired when an element became visible/invisible in the browser viewport.

$('someselector').appear(); // It supports optional hash with "force_process" and "interval" keys. Check source code for details.
$('someselector').appear(); // It supports optional Object with options:
{
interval: 250 // delay between event-binding and actual processing of the elements
force_process: false // trigger processing after binding (after the delay)
scroll_selector: window // element that triggers appear on scroll
}

$('<div>test</div>').appear(); // It also supports raw DOM nodes wrapped in jQuery.

Expand Down
78 changes: 50 additions & 28 deletions jquery.appear.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,29 @@
*
* https://github.com/morr/jquery.appear/
*
* Version: 0.3.6
* Version: 0.3.7
*/
(function($) {
(function ($) {
var selectors = [];

var check_binded = false;
var check_binded = [];
var check_lock = false;
var defaults = {
interval: 250,
force_process: false
force_process: false,
/**
* @type {Object} to which the scroll-event is bound, default 'window'
*/
scroll_selector: window
};
var $window = $(window);

var $prior_appeared = [];

function appeared(selector) {
return $(selector).filter(function() {
return $(this).is(':appeared');
});
}

function process() {
check_lock = false;
for (var index = 0, selectorsLength = selectors.length; index < selectorsLength; index++) {
var $appeared = appeared(selectors[index]);
var $appeared = $(selectors[index]).filter(function () {
return $(this).is(':appeared');
});

$appeared.trigger('appear', [$appeared]);

Expand All @@ -48,22 +46,27 @@
}

// "appeared" custom filter
$.expr[':'].appeared = function(element) {
$.expr[':']['appeared'] = function (element) {
var $element = $(element);
if (!$element.is(':visible')) {
return false;
}

var window_left = $window.scrollLeft();
var window_top = $window.scrollTop();
/**
* @type {jQuery} scrollable container
*/
var $scroll_selector = $element.data('scroll_selector');

var window_left = $scroll_selector.scrollLeft();
var window_top = $scroll_selector.scrollTop();
var offset = $element.offset();
var left = offset.left;
var top = offset.top;

if (top + $element.height() >= window_top &&
top - ($element.data('appear-top-offset') || 0) <= window_top + $window.height() &&
left + $element.width() >= window_left &&
left - ($element.data('appear-left-offset') || 0) <= window_left + $window.width()) {
top - ($element.data('appear-top-offset') || 0) <= window_top + $scroll_selector.height() &&
left + $element.width() >= window_left &&
left - ($element.data('appear-left-offset') || 0) <= window_left + $scroll_selector.width()) {
return true;
} else {
return false;
Expand All @@ -72,11 +75,23 @@

$.fn.extend({
// watching for element's appearance in browser viewport
appear: function(options) {
appear: function (options) {
var opts = $.extend({}, defaults, options || {});
/**
* @type {jQuery} scrollable container
*/
var $scrollSelector = $(opts.scroll_selector);
var scrollSelectorName = $scrollSelector.selector || 'default';

// add the scroll selector to each element, so it is accessable in the :appeared check
this.each(function () {
$(this).data('scroll_selector', $scrollSelector);
});

var selector = this.selector || this;
if (!check_binded) {
var on_check = function() {
// no binding on it yet
if ($.inArray(scrollSelectorName, check_binded) == -1) {
var on_check = function () {
if (check_lock) {
return;
}
Expand All @@ -85,8 +100,15 @@
setTimeout(process, opts.interval);
};

$(window).scroll(on_check).resize(on_check);
check_binded = true;
$scrollSelector.on('scroll', on_check);

// no resize-binding on window yet
if (check_binded.length == 0) {
$(window).on('resize', on_check);
}

// mark it as bound
check_binded.push(scrollSelectorName);
}

if (opts.force_process) {
Expand All @@ -99,19 +121,19 @@

$.extend({
// force elements's appearance check
force_appear: function() {
if (check_binded) {
force_appear: function () {
if (check_binded.length > 0) {
process();
return true;
}
return false;
}
});
})(function() {
})(function () {
if (typeof module !== 'undefined') {
// Node
return require('jquery');
} else {
return jQuery;
}
}());
}());