|
@ -65,7 +65,11 @@ $.fn.visibility = function(parameters) { |
|
|
module.bindEvents(); |
|
|
module.bindEvents(); |
|
|
module.instantiate(); |
|
|
module.instantiate(); |
|
|
|
|
|
|
|
|
setTimeout(module.checkVisibility, settings.loadWait); |
|
|
|
|
|
|
|
|
if(settings.type == 'image') { |
|
|
|
|
|
module.setup.image(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
requestAnimationFrame(module.checkVisibility); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
instantiate: function() { |
|
|
instantiate: function() { |
|
@ -88,6 +92,7 @@ $.fn.visibility = function(parameters) { |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
bindEvents: function() { |
|
|
bindEvents: function() { |
|
|
|
|
|
module.verbose('Binding visibility events to scroll and resize'); |
|
|
$window |
|
|
$window |
|
|
.on('resize', module.event.refresh) |
|
|
.on('resize', module.event.refresh) |
|
|
.on('scroll', module.event.scroll) |
|
|
.on('scroll', module.event.scroll) |
|
@ -99,25 +104,99 @@ $.fn.visibility = function(parameters) { |
|
|
requestAnimationFrame(module.refresh); |
|
|
requestAnimationFrame(module.refresh); |
|
|
}, |
|
|
}, |
|
|
scroll: function() { |
|
|
scroll: function() { |
|
|
requestAnimationFrame(module.checkVisibility); |
|
|
|
|
|
|
|
|
module.verbose('Scroll position changed'); |
|
|
|
|
|
if(settings.throttle) { |
|
|
|
|
|
clearTimeout(module.timer); |
|
|
|
|
|
module.timer = setTimeout(module.checkVisibility, 200); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
requestAnimationFrame(module.checkVisibility); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
precache: function(images, callback) { |
|
|
|
|
|
if (!(images instanceof Array)) { |
|
|
|
|
|
images = [images]; |
|
|
|
|
|
} |
|
|
|
|
|
var |
|
|
|
|
|
imagesLength = images.length, |
|
|
|
|
|
loadedCounter = 0, |
|
|
|
|
|
cache = [], |
|
|
|
|
|
cacheImage = document.createElement('img'), |
|
|
|
|
|
handleLoad = function() { |
|
|
|
|
|
loadedCounter++; |
|
|
|
|
|
if (loadedCounter >= images.length) { |
|
|
|
|
|
if ($.isFunction(callback)) { |
|
|
|
|
|
callback(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
; |
|
|
|
|
|
while (imagesLength--) { |
|
|
|
|
|
cacheImage = document.createElement('img'); |
|
|
|
|
|
cacheImage.onload = handleLoad; |
|
|
|
|
|
cacheImage.onerror = handleLoad; |
|
|
|
|
|
cacheImage.src = images[imagesLength]; |
|
|
|
|
|
cache.push(cacheImage); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
setup: { |
|
|
|
|
|
image: function() { |
|
|
|
|
|
var |
|
|
|
|
|
src = $module.data('src') |
|
|
|
|
|
; |
|
|
|
|
|
if(src) { |
|
|
|
|
|
module.verbose('Lazy loading image', src); |
|
|
|
|
|
settings.once = true; |
|
|
|
|
|
// show when top visible
|
|
|
|
|
|
module.topVisible(function() { |
|
|
|
|
|
module.precache(src, function() { |
|
|
|
|
|
module.set.image(src); |
|
|
|
|
|
settings.onTopVisible = false; |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
set: { |
|
|
|
|
|
image: function(src) { |
|
|
|
|
|
var |
|
|
|
|
|
offScreen = (module.cache.screen.bottom + settings.offset < module.cache.element.top) |
|
|
|
|
|
; |
|
|
|
|
|
$module |
|
|
|
|
|
.attr('src', src) |
|
|
|
|
|
; |
|
|
|
|
|
if($.fn.transition !== undefined || offScreen) { |
|
|
|
|
|
$module.transition(settings.transition, settings.duration); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
$module.fadeIn(settings.duration); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
refresh: function() { |
|
|
refresh: function() { |
|
|
|
|
|
module.debug('Refreshing constants (element width/height)'); |
|
|
|
|
|
module.reset(); |
|
|
module.save.position(); |
|
|
module.save.position(); |
|
|
module.checkVisibility(); |
|
|
module.checkVisibility(); |
|
|
$.proxy(settings.onRefresh, element)(); |
|
|
$.proxy(settings.onRefresh, element)(); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
reset: function() { |
|
|
reset: function() { |
|
|
|
|
|
module.verbose('Reseting all cached values'); |
|
|
module.cache = { |
|
|
module.cache = { |
|
|
|
|
|
occurred: {}, |
|
|
screen : {}, |
|
|
screen : {}, |
|
|
element : {} |
|
|
element : {} |
|
|
}; |
|
|
}; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
checkVisibility: function() { |
|
|
checkVisibility: function() { |
|
|
module.verbose('Updating visibility of element', module.cache.element); |
|
|
|
|
|
|
|
|
module.verbose('Checking visibility of element', module.cache.element); |
|
|
module.save.scroll(); |
|
|
module.save.scroll(); |
|
|
module.save.direction(); |
|
|
module.save.direction(); |
|
|
module.save.screenCalculations(); |
|
|
module.save.screenCalculations(); |
|
@ -131,24 +210,6 @@ $.fn.visibility = function(parameters) { |
|
|
module.bottomPassed(); |
|
|
module.bottomPassed(); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
passing: function(newCallback) { |
|
|
|
|
|
var |
|
|
|
|
|
calculations = module.get.elementCalculations(), |
|
|
|
|
|
screen = module.get.screenCalculations(), |
|
|
|
|
|
callback = newCallback || settings.onPassing |
|
|
|
|
|
; |
|
|
|
|
|
if(newCallback) { |
|
|
|
|
|
module.debug('Adding callback for passing', newCallback); |
|
|
|
|
|
settings.onPassing = newCallback; |
|
|
|
|
|
} |
|
|
|
|
|
if(callback && calculations.passing) { |
|
|
|
|
|
$.proxy(callback, element)(calculations, screen); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
return calculations.passing; |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
passed: function(amount, newCallback) { |
|
|
passed: function(amount, newCallback) { |
|
|
var |
|
|
var |
|
|
calculations = module.get.elementCalculations(), |
|
|
calculations = module.get.elementCalculations(), |
|
@ -164,26 +225,54 @@ $.fn.visibility = function(parameters) { |
|
|
else if(calculations.passing) { |
|
|
else if(calculations.passing) { |
|
|
$.each(settings.onPassed, function(amount, callback) { |
|
|
$.each(settings.onPassed, function(amount, callback) { |
|
|
if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) { |
|
|
if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) { |
|
|
callback(); |
|
|
|
|
|
|
|
|
module.execute(callback, amount); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
module.remove.occurred(callback, amount); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
passing: function(newCallback) { |
|
|
|
|
|
var |
|
|
|
|
|
calculations = module.get.elementCalculations(), |
|
|
|
|
|
callback = newCallback || settings.onPassing, |
|
|
|
|
|
callbackName = 'passing' |
|
|
|
|
|
; |
|
|
|
|
|
if(newCallback) { |
|
|
|
|
|
module.debug('Adding callback for passing', newCallback); |
|
|
|
|
|
settings.onPassing = newCallback; |
|
|
|
|
|
} |
|
|
|
|
|
if(callback && calculations.passing) { |
|
|
|
|
|
module.execute(callback, callbackName); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
module.remove.occurred(callbackName); |
|
|
|
|
|
} |
|
|
|
|
|
if(newCallback !== undefined) { |
|
|
|
|
|
return calculations.passing; |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
topVisible: function(newCallback) { |
|
|
topVisible: function(newCallback) { |
|
|
var |
|
|
var |
|
|
calculations = module.get.elementCalculations(), |
|
|
calculations = module.get.elementCalculations(), |
|
|
screen = module.get.screenCalculations(), |
|
|
|
|
|
callback = newCallback || settings.onTopVisible |
|
|
|
|
|
|
|
|
callback = newCallback || settings.onTopVisible, |
|
|
|
|
|
callbackName = 'topVisible' |
|
|
; |
|
|
; |
|
|
if(newCallback) { |
|
|
if(newCallback) { |
|
|
module.debug('Adding callback for top visible', newCallback); |
|
|
module.debug('Adding callback for top visible', newCallback); |
|
|
settings.onTopVisible = newCallback; |
|
|
settings.onTopVisible = newCallback; |
|
|
} |
|
|
} |
|
|
if(callback && calculations.topVisible) { |
|
|
if(callback && calculations.topVisible) { |
|
|
$.proxy(callback, element)(calculations, screen); |
|
|
|
|
|
|
|
|
module.execute(callback, callbackName); |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
|
|
|
module.remove.occurred(callbackName); |
|
|
|
|
|
} |
|
|
|
|
|
if(newCallback === undefined) { |
|
|
return calculations.topVisible; |
|
|
return calculations.topVisible; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
@ -191,17 +280,20 @@ $.fn.visibility = function(parameters) { |
|
|
bottomVisible: function(newCallback) { |
|
|
bottomVisible: function(newCallback) { |
|
|
var |
|
|
var |
|
|
calculations = module.get.elementCalculations(), |
|
|
calculations = module.get.elementCalculations(), |
|
|
screen = module.get.screenCalculations(), |
|
|
|
|
|
callback = newCallback || settings.onBottomVisible |
|
|
|
|
|
|
|
|
callback = newCallback || settings.onBottomVisible, |
|
|
|
|
|
callbackName = 'bottomVisible' |
|
|
; |
|
|
; |
|
|
if(newCallback) { |
|
|
if(newCallback) { |
|
|
module.debug('Adding callback for bottom visible', newCallback); |
|
|
module.debug('Adding callback for bottom visible', newCallback); |
|
|
settings.onBottomVisible = newCallback; |
|
|
settings.onBottomVisible = newCallback; |
|
|
} |
|
|
} |
|
|
if(callback && calculations.bottomVisible) { |
|
|
if(callback && calculations.bottomVisible) { |
|
|
$.proxy(callback, element)(calculations, screen); |
|
|
|
|
|
|
|
|
module.execute(callback, callbackName); |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
|
|
|
module.remove.occurred(callbackName); |
|
|
|
|
|
} |
|
|
|
|
|
if(newCallback === undefined) { |
|
|
return calculations.bottomVisible; |
|
|
return calculations.bottomVisible; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
@ -209,17 +301,20 @@ $.fn.visibility = function(parameters) { |
|
|
topPassed: function(newCallback) { |
|
|
topPassed: function(newCallback) { |
|
|
var |
|
|
var |
|
|
calculations = module.get.elementCalculations(), |
|
|
calculations = module.get.elementCalculations(), |
|
|
screen = module.get.screenCalculations(), |
|
|
|
|
|
callback = newCallback || settings.onTopPassed |
|
|
|
|
|
|
|
|
callback = newCallback || settings.onTopPassed, |
|
|
|
|
|
callbackName = 'topPassed' |
|
|
; |
|
|
; |
|
|
if(newCallback) { |
|
|
if(newCallback) { |
|
|
module.debug('Adding callback for top passed', newCallback); |
|
|
module.debug('Adding callback for top passed', newCallback); |
|
|
settings.onTopPassed = newCallback; |
|
|
settings.onTopPassed = newCallback; |
|
|
} |
|
|
} |
|
|
if(callback && calculations.topPassed) { |
|
|
if(callback && calculations.topPassed) { |
|
|
$.proxy(callback, element)(calculations, screen); |
|
|
|
|
|
|
|
|
module.execute(callback, callbackName); |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
|
|
|
module.remove.occurred(callbackName); |
|
|
|
|
|
} |
|
|
|
|
|
if(newCallback === undefined) { |
|
|
return calculations.topPassed; |
|
|
return calculations.topPassed; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
@ -227,22 +322,56 @@ $.fn.visibility = function(parameters) { |
|
|
bottomPassed: function(newCallback) { |
|
|
bottomPassed: function(newCallback) { |
|
|
var |
|
|
var |
|
|
calculations = module.get.elementCalculations(), |
|
|
calculations = module.get.elementCalculations(), |
|
|
screen = module.get.screenCalculations(), |
|
|
|
|
|
callback = newCallback || settings.onBottomPassed |
|
|
|
|
|
|
|
|
callback = newCallback || settings.onBottomPassed, |
|
|
|
|
|
callbackName = 'bottomPassed' |
|
|
; |
|
|
; |
|
|
if(newCallback) { |
|
|
if(newCallback) { |
|
|
module.debug('Adding callback for bottom passed', newCallback); |
|
|
module.debug('Adding callback for bottom passed', newCallback); |
|
|
settings.bottomPassed = newCallback; |
|
|
settings.bottomPassed = newCallback; |
|
|
} |
|
|
} |
|
|
if(callback && calculations.bottomPassed) { |
|
|
if(callback && calculations.bottomPassed) { |
|
|
$.proxy(callback, element)(calculations, screen); |
|
|
|
|
|
|
|
|
module.execute(callback, callbackName); |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
|
|
|
module.remove.occurred(callbackName); |
|
|
|
|
|
} |
|
|
|
|
|
if(newCallback === undefined) { |
|
|
return calculations.bottomPassed; |
|
|
return calculations.bottomPassed; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
execute: function(callback, callbackName) { |
|
|
|
|
|
var |
|
|
|
|
|
calculations = module.get.elementCalculations(), |
|
|
|
|
|
screen = module.get.screenCalculations() |
|
|
|
|
|
; |
|
|
|
|
|
if(settings.once && module.get.occurred(callbackName)) { |
|
|
|
|
|
// multiple callbacks are ignored when times == 'once'
|
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
module.debug('Conditions met for callback', callbackName, calculations); |
|
|
|
|
|
$.proxy(callback, element)(calculations, screen); |
|
|
|
|
|
} |
|
|
|
|
|
module.save.occurred(callbackName); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
remove: { |
|
|
|
|
|
occurred: function(callback) { |
|
|
|
|
|
if(callback) { |
|
|
|
|
|
module.cache.occurred[callback] = false; |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
module.cache.occurred = {}; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
save: { |
|
|
save: { |
|
|
|
|
|
occurred: function(callback) { |
|
|
|
|
|
if(callback) { |
|
|
|
|
|
module.cache.occurred[callback] = true; |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
scroll: function() { |
|
|
scroll: function() { |
|
|
module.cache.scroll = $window.scrollTop() + settings.offset; |
|
|
module.cache.scroll = $window.scrollTop() + settings.offset; |
|
|
}, |
|
|
}, |
|
@ -329,8 +458,8 @@ $.fn.visibility = function(parameters) { |
|
|
} |
|
|
} |
|
|
module.save.direction(); |
|
|
module.save.direction(); |
|
|
$.extend(module.cache.screen, { |
|
|
$.extend(module.cache.screen, { |
|
|
top : scroll + settings.offset, |
|
|
|
|
|
bottom : scroll + settings.offset + module.cache.screen.height |
|
|
|
|
|
|
|
|
top : scroll - settings.offset, |
|
|
|
|
|
bottom : scroll - settings.offset + module.cache.screen.height |
|
|
}); |
|
|
}); |
|
|
return module.cache.screen; |
|
|
return module.cache.screen; |
|
|
}, |
|
|
}, |
|
@ -356,6 +485,12 @@ $.fn.visibility = function(parameters) { |
|
|
} |
|
|
} |
|
|
return parseInt(amount, 10); |
|
|
return parseInt(amount, 10); |
|
|
}, |
|
|
}, |
|
|
|
|
|
occurred: function(callback) { |
|
|
|
|
|
return (module.cache.occurred !== undefined) |
|
|
|
|
|
? module.cache.occurred[callback] || false |
|
|
|
|
|
: false |
|
|
|
|
|
; |
|
|
|
|
|
}, |
|
|
direction: function() { |
|
|
direction: function() { |
|
|
if(module.cache.direction === undefined) { |
|
|
if(module.cache.direction === undefined) { |
|
|
module.save.direction(); |
|
|
module.save.direction(); |
|
@ -585,12 +720,17 @@ $.fn.visibility.settings = { |
|
|
verbose : false, |
|
|
verbose : false, |
|
|
performance : true, |
|
|
performance : true, |
|
|
|
|
|
|
|
|
loadWait : 1000, |
|
|
|
|
|
|
|
|
|
|
|
watch : true, |
|
|
|
|
|
offset : 0, |
|
|
offset : 0, |
|
|
includeMargin : false, |
|
|
includeMargin : false, |
|
|
|
|
|
|
|
|
|
|
|
// visibility check delay in ms
|
|
|
|
|
|
throttle : false, |
|
|
|
|
|
|
|
|
|
|
|
// special visibility type
|
|
|
|
|
|
type : false, |
|
|
|
|
|
transition : 'fade in', |
|
|
|
|
|
duration : 500, |
|
|
|
|
|
|
|
|
// array of callbacks
|
|
|
// array of callbacks
|
|
|
onPassed : {}, |
|
|
onPassed : {}, |
|
|
|
|
|
|
|
@ -601,10 +741,15 @@ $.fn.visibility.settings = { |
|
|
onTopPassed : false, |
|
|
onTopPassed : false, |
|
|
onBottomPassed : false, |
|
|
onBottomPassed : false, |
|
|
|
|
|
|
|
|
|
|
|
once : false, |
|
|
|
|
|
|
|
|
// utility callbacks
|
|
|
// utility callbacks
|
|
|
onRefresh : function(){}, |
|
|
onRefresh : function(){}, |
|
|
onScroll : function(){}, |
|
|
onScroll : function(){}, |
|
|
|
|
|
|
|
|
|
|
|
// not used currently waiting for (DOM Mutations API adoption)
|
|
|
|
|
|
// https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#mutation-observers
|
|
|
|
|
|
watch : true, |
|
|
watchedProperties : [ |
|
|
watchedProperties : [ |
|
|
'offsetWidth', |
|
|
'offsetWidth', |
|
|
'offsetHeight', |
|
|
'offsetHeight', |
|
|