From dd010b02d9080fc7baf425f2513719abb950cece Mon Sep 17 00:00:00 2001 From: jlukic Date: Tue, 19 May 2015 13:02:30 -0400 Subject: [PATCH] Add new sticky behavior, automatically creates placeholder content --- RELEASE-NOTES.md | 1 + src/definitions/behaviors/visibility.js | 102 ++++++++++++++++-------- 2 files changed, 68 insertions(+), 35 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index e9b7400f2..14b42dbc0 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -43,6 +43,7 @@ - **Shapes** - Shapes now animate height/width when side changes sizes and now correctly adjusts for margin on shape elements - **Steps** - Steps now use `flexbox`, the default horizontal theme has the active element point downward now instead of to the right. Steps no longer need `item count` and will automatically divide evenly - **Transition** - Transition has been optimized to be much more performant. +- **Visibility** - Visibility can now handle "sticky" `fixed` content, adding a placeholder duplicate element which will automatically appear when an element swaps to fixed position - **Visibility** - Visibility and sticky now are much more performance and include two new callbacks `onOnScreen` and `onOffScreen` **Enhancements** diff --git a/src/definitions/behaviors/visibility.js b/src/definitions/behaviors/visibility.js index ed92ca887..ca6f74235 100644 --- a/src/definitions/behaviors/visibility.js +++ b/src/definitions/behaviors/visibility.js @@ -37,6 +37,7 @@ $.fn.visibility = function(parameters) { className = settings.className, namespace = settings.namespace, error = settings.error, + metadata = settings.metadata, eventNamespace = '.' + namespace, moduleNamespace = 'module-' + namespace, @@ -45,8 +46,10 @@ $.fn.visibility = function(parameters) { $module = $(this), $context = $(settings.context), - selector = $module.selector || '', + $placeholder, + + selector = $module.selector || '', instance = $module.data(moduleNamespace), requestAnimationFrame = window.requestAnimationFrame @@ -66,23 +69,27 @@ $.fn.visibility = function(parameters) { module.debug('Initializing', settings); module.setup.cache(); - module.save.position(); if( module.should.trackChanges() ) { - module.bind.events(); + if(settings.type == 'image') { module.setup.image(); } if(settings.type == 'fixed') { module.setup.fixed(); } + if(settings.observeChanges) { module.observeChanges(); } - if( !module.is.visible() ) { - module.error(error.visible, $module); - } + module.bind.events(); } + + module.save.position(); + if( !module.is.visible() ) { + module.error(error.visible, $module); + } + if(settings.initialCheck) { module.checkVisibility(); } @@ -138,8 +145,12 @@ $.fn.visibility = function(parameters) { bind: { events: function() { module.verbose('Binding visibility events to scroll and resize'); + if(settings.refreshOnLoad) { + $window + .on('load' + eventNamespace, module.event.load) + ; + } $window - .on('load' + eventNamespace, module.event.load) .on('resize' + eventNamespace, module.event.resize) ; // pub/sub pattern @@ -260,29 +271,48 @@ $.fn.visibility = function(parameters) { }, image: function() { var - src = $module.data('src') + src = $module.data(metadata.src) ; if(src) { module.verbose('Lazy loading image', src); + settings.once = true; settings.observeChanges = false; + // show when top visible - module.topVisible(function() { + settings.onTopVisible = function() { module.debug('Image top visible', element); module.precache(src, function() { module.set.image(src); - settings.onTopVisible = false; }); - }); + }; } }, fixed: function() { - module.verbose('Setting up fixed on element pass'); - settings.once = false; + module.debug('Setting up fixed'); + settings.once = false; + settings.observeChanges = false; + settings.refreshOnLoad = false; + if(!parameters.transition) { + settings.transition = false; + } + $placeholder = $module + .clone(false) + .css('display', 'none') + .addClass(className.placeholder) + .insertBefore($module) + ; + module.debug('Added placeholder', $placeholder); settings.onTopPassed = function() { + module.debug('Element passed, adding fixed position', $module); + $placeholder + .css('display', 'block') + ; $module .addClass(className.fixed) .css({ - top: settings.offset + 'px' + position : 'fixed', + top : settings.offset + 'px', + zIndex : '1' }) ; if(settings.transition) { @@ -292,11 +322,16 @@ $.fn.visibility = function(parameters) { } }; settings.onTopPassedReverse = function() { + module.debug('Element returned to position, removing fixed', $module); + $placeholder + .css('display', 'none') + ; $module .removeClass(className.fixed) .css({ - position: '', - top: '' + position : '', + top : '', + zIndex : '' }) ; }; @@ -305,29 +340,20 @@ $.fn.visibility = function(parameters) { set: { image: function(src) { - var - offScreen = (module.cache.screen.bottom < module.cache.element.top) - ; $module .attr('src', src) ; - if(offScreen) { - module.verbose('Image outside browser, no show animation'); - $module.show(); - } - else { - if(settings.transition) { - if( $.fn.transition !== undefined ) { - $module.transition(settings.transition, settings.duration); - } - else { - $module.fadeIn(settings.duration); - } + if(settings.transition) { + if( $.fn.transition !== undefined ) { + $module.transition(settings.transition, settings.duration); } else { - $module.show(); + $module.fadeIn(settings.duration); } } + else { + $module.show(); + } } }, @@ -346,7 +372,7 @@ $.fn.visibility = function(parameters) { }, visible: function() { if(module.cache && module.cache.element) { - return (module.cache.element.width > 0); + return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0); } return false; } @@ -354,6 +380,7 @@ $.fn.visibility = function(parameters) { refresh: function() { module.debug('Refreshing constants (width/height)'); + console.log('here'); module.reset(); module.save.position(); module.checkVisibility(); @@ -1121,7 +1148,7 @@ $.fn.visibility.settings = { type : false, // image only animation settings - transition : false, + transition : 'fade in', duration : 1000, // array of callbacks for percentage @@ -1147,8 +1174,13 @@ $.fn.visibility.settings = { onUpdate : false, // disabled by default for performance onRefresh : function(){}, + metadata : { + src: 'src' + }, + className: { - fixed: 'fixed' + fixed : 'fixed', + placeholder : 'placeholder' }, error : {