1 line
16 KiB
JavaScript
1 line
16 KiB
JavaScript
!function(e,o,n,t){"use strict";o=void 0!==o&&o.Math==Math?o:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),e.fn.visibility=function(t){var i,s=e(this),c=s.selector||"",r=(new Date).getTime(),a=[],l=arguments[0],d="string"==typeof l,u=[].slice.call(arguments,1),f=s.length,v=0;return s.each(function(){var s,b,m,g,p=e.isPlainObject(t)?e.extend(!0,{},e.fn.visibility.settings,t):e.extend({},e.fn.visibility.settings),h=p.className,P=p.namespace,x=p.error,C=p.metadata,y="."+P,R="module-"+P,S=e(o),V=e(this),k=e(p.context),T=(V.selector,V.data(R)),O=o.requestAnimationFrame||o.mozRequestAnimationFrame||o.webkitRequestAnimationFrame||o.msRequestAnimationFrame||function(e){setTimeout(e,0)},z=this,A=!1;g={initialize:function(){g.debug("Initializing",p),g.setup.cache(),g.should.trackChanges()&&("image"==p.type&&g.setup.image(),"fixed"==p.type&&g.setup.fixed(),p.observeChanges&&g.observeChanges(),g.bind.events()),g.save.position(),g.is.visible()||g.error(x.visible,V),p.initialCheck&&g.checkVisibility(),g.instantiate()},instantiate:function(){g.debug("Storing instance",g),V.data(R,g),T=g},destroy:function(){g.verbose("Destroying previous module"),m&&m.disconnect(),b&&b.disconnect(),S.off("load"+y,g.event.load).off("resize"+y,g.event.resize),k.off("scroll"+y,g.event.scroll).off("scrollchange"+y,g.event.scrollchange),"fixed"==p.type&&(g.resetFixed(),g.remove.placeholder()),V.off(y).removeData(R)},observeChanges:function(){"MutationObserver"in o&&(b=new MutationObserver(g.event.contextChanged),m=new MutationObserver(g.event.changed),b.observe(n,{childList:!0,subtree:!0}),m.observe(z,{childList:!0,subtree:!0}),g.debug("Setting up mutation observer",m))},bind:{events:function(){g.verbose("Binding visibility events to scroll and resize"),p.refreshOnLoad&&S.on("load"+y,g.event.load),S.on("resize"+y,g.event.resize),k.off("scroll"+y).on("scroll"+y,g.event.scroll).on("scrollchange"+y,g.event.scrollchange)}},event:{changed:function(e){g.verbose("DOM tree modified, updating visibility calculations"),g.timer=setTimeout(function(){g.verbose("DOM tree modified, updating sticky menu"),g.refresh()},100)},contextChanged:function(o){[].forEach.call(o,function(o){o.removedNodes&&[].forEach.call(o.removedNodes,function(o){(o==z||e(o).find(z).length>0)&&(g.debug("Element removed from DOM, tearing down events"),g.destroy())})})},resize:function(){g.debug("Window resized"),p.refreshOnResize&&O(g.refresh)},load:function(){g.debug("Page finished loading"),O(g.refresh)},scroll:function(){p.throttle?(clearTimeout(g.timer),g.timer=setTimeout(function(){k.triggerHandler("scrollchange"+y,[k.scrollTop()])},p.throttle)):O(function(){k.triggerHandler("scrollchange"+y,[k.scrollTop()])})},scrollchange:function(e,o){g.checkVisibility(o)}},precache:function(o,t){o instanceof Array||(o=[o]);for(var i=o.length,s=0,c=[],r=n.createElement("img"),a=function(){++s>=o.length&&e.isFunction(t)&&t()};i--;)r=n.createElement("img"),r.onload=a,r.onerror=a,r.src=o[i],c.push(r)},enableCallbacks:function(){g.debug("Allowing callbacks to occur"),A=!1},disableCallbacks:function(){g.debug("Disabling all callbacks temporarily"),A=!0},should:{trackChanges:function(){return d?(g.debug("One time query, no need to bind events"),!1):(g.debug("Callbacks being attached"),!0)}},setup:{cache:function(){g.cache={occurred:{},screen:{},element:{}}},image:function(){var e=V.data(C.src);e&&(g.verbose("Lazy loading image",e),p.once=!0,p.observeChanges=!1,p.onOnScreen=function(){g.debug("Image on screen",z),g.precache(e,function(){g.set.image(e,function(){v++,v==f&&p.onAllLoaded.call(this),p.onLoad.call(this)})})})},fixed:function(){g.debug("Setting up fixed"),p.once=!1,p.observeChanges=!1,p.initialCheck=!0,p.refreshOnLoad=!0,t.transition||(p.transition=!1),g.create.placeholder(),g.debug("Added placeholder",s),p.onTopPassed=function(){g.debug("Element passed, adding fixed position",V),g.show.placeholder(),g.set.fixed(),p.transition&&void 0!==e.fn.transition&&V.transition(p.transition,p.duration)},p.onTopPassedReverse=function(){g.debug("Element returned to position, removing fixed",V),g.hide.placeholder(),g.remove.fixed()}}},create:{placeholder:function(){g.verbose("Creating fixed position placeholder"),s=V.clone(!1).css("display","none").addClass(h.placeholder).insertAfter(V)}},show:{placeholder:function(){g.verbose("Showing placeholder"),s.css("display","block").css("visibility","hidden")}},hide:{placeholder:function(){g.verbose("Hiding placeholder"),s.css("display","none").css("visibility","")}},set:{fixed:function(){g.verbose("Setting element to fixed position"),V.addClass(h.fixed).css({position:"fixed",top:p.offset+"px",left:"auto",zIndex:p.zIndex}),p.onFixed.call(z)},image:function(o,n){if(V.attr("src",o),p.transition)if(void 0!==e.fn.transition){if(V.hasClass(h.visible))return void g.debug("Transition already occurred on this image, skipping animation");V.transition(p.transition,p.duration,n)}else V.fadeIn(p.duration,n);else V.show()}},is:{onScreen:function(){return g.get.elementCalculations().onScreen},offScreen:function(){return g.get.elementCalculations().offScreen},visible:function(){return!(!g.cache||!g.cache.element)&&!(0===g.cache.element.width&&0===g.cache.element.offset.top)},verticallyScrollableContext:function(){var e=k.get(0)!==o&&k.css("overflow-y");return"auto"==e||"scroll"==e},horizontallyScrollableContext:function(){var e=k.get(0)!==o&&k.css("overflow-x");return"auto"==e||"scroll"==e}},refresh:function(){g.debug("Refreshing constants (width/height)"),"fixed"==p.type&&g.resetFixed(),g.reset(),g.save.position(),p.checkOnRefresh&&g.checkVisibility(),p.onRefresh.call(z)},resetFixed:function(){g.remove.fixed(),g.remove.occurred()},reset:function(){g.verbose("Resetting all cached values"),e.isPlainObject(g.cache)&&(g.cache.screen={},g.cache.element={})},checkVisibility:function(e){g.verbose("Checking visibility of element",g.cache.element),!A&&g.is.visible()&&(g.save.scroll(e),g.save.calculations(),g.passed(),g.passingReverse(),g.topVisibleReverse(),g.bottomVisibleReverse(),g.topPassedReverse(),g.bottomPassedReverse(),g.onScreen(),g.offScreen(),g.passing(),g.topVisible(),g.bottomVisible(),g.topPassed(),g.bottomPassed(),p.onUpdate&&p.onUpdate.call(z,g.get.elementCalculations()))},passed:function(o,n){var t=g.get.elementCalculations();if(o&&n)p.onPassed[o]=n;else{if(void 0!==o)return g.get.pixelsPassed(o)>t.pixelsPassed;t.passing&&e.each(p.onPassed,function(e,o){t.bottomVisible||t.pixelsPassed>g.get.pixelsPassed(e)?g.execute(o,e):p.once||g.remove.occurred(o)})}},onScreen:function(e){var o=g.get.elementCalculations(),n=e||p.onOnScreen;if(e&&(g.debug("Adding callback for onScreen",e),p.onOnScreen=e),o.onScreen?g.execute(n,"onScreen"):p.once||g.remove.occurred("onScreen"),void 0!==e)return o.onOnScreen},offScreen:function(e){var o=g.get.elementCalculations(),n=e||p.onOffScreen;if(e&&(g.debug("Adding callback for offScreen",e),p.onOffScreen=e),o.offScreen?g.execute(n,"offScreen"):p.once||g.remove.occurred("offScreen"),void 0!==e)return o.onOffScreen},passing:function(e){var o=g.get.elementCalculations(),n=e||p.onPassing;if(e&&(g.debug("Adding callback for passing",e),p.onPassing=e),o.passing?g.execute(n,"passing"):p.once||g.remove.occurred("passing"),void 0!==e)return o.passing},topVisible:function(e){var o=g.get.elementCalculations(),n=e||p.onTopVisible;if(e&&(g.debug("Adding callback for top visible",e),p.onTopVisible=e),o.topVisible?g.execute(n,"topVisible"):p.once||g.remove.occurred("topVisible"),void 0===e)return o.topVisible},bottomVisible:function(e){var o=g.get.elementCalculations(),n=e||p.onBottomVisible;if(e&&(g.debug("Adding callback for bottom visible",e),p.onBottomVisible=e),o.bottomVisible?g.execute(n,"bottomVisible"):p.once||g.remove.occurred("bottomVisible"),void 0===e)return o.bottomVisible},topPassed:function(e){var o=g.get.elementCalculations(),n=e||p.onTopPassed;if(e&&(g.debug("Adding callback for top passed",e),p.onTopPassed=e),o.topPassed?g.execute(n,"topPassed"):p.once||g.remove.occurred("topPassed"),void 0===e)return o.topPassed},bottomPassed:function(e){var o=g.get.elementCalculations(),n=e||p.onBottomPassed;if(e&&(g.debug("Adding callback for bottom passed",e),p.onBottomPassed=e),o.bottomPassed?g.execute(n,"bottomPassed"):p.once||g.remove.occurred("bottomPassed"),void 0===e)return o.bottomPassed},passingReverse:function(e){var o=g.get.elementCalculations(),n=e||p.onPassingReverse;if(e&&(g.debug("Adding callback for passing reverse",e),p.onPassingReverse=e),o.passing?p.once||g.remove.occurred("passingReverse"):g.get.occurred("passing")&&g.execute(n,"passingReverse"),void 0!==e)return!o.passing},topVisibleReverse:function(e){var o=g.get.elementCalculations(),n=e||p.onTopVisibleReverse;if(e&&(g.debug("Adding callback for top visible reverse",e),p.onTopVisibleReverse=e),o.topVisible?p.once||g.remove.occurred("topVisibleReverse"):g.get.occurred("topVisible")&&g.execute(n,"topVisibleReverse"),void 0===e)return!o.topVisible},bottomVisibleReverse:function(e){var o=g.get.elementCalculations(),n=e||p.onBottomVisibleReverse;if(e&&(g.debug("Adding callback for bottom visible reverse",e),p.onBottomVisibleReverse=e),o.bottomVisible?p.once||g.remove.occurred("bottomVisibleReverse"):g.get.occurred("bottomVisible")&&g.execute(n,"bottomVisibleReverse"),void 0===e)return!o.bottomVisible},topPassedReverse:function(e){var o=g.get.elementCalculations(),n=e||p.onTopPassedReverse;if(e&&(g.debug("Adding callback for top passed reverse",e),p.onTopPassedReverse=e),o.topPassed?p.once||g.remove.occurred("topPassedReverse"):g.get.occurred("topPassed")&&g.execute(n,"topPassedReverse"),void 0===e)return!o.onTopPassed},bottomPassedReverse:function(e){var o=g.get.elementCalculations(),n=e||p.onBottomPassedReverse;if(e&&(g.debug("Adding callback for bottom passed reverse",e),p.onBottomPassedReverse=e),o.bottomPassed?p.once||g.remove.occurred("bottomPassedReverse"):g.get.occurred("bottomPassed")&&g.execute(n,"bottomPassedReverse"),void 0===e)return!o.bottomPassed},execute:function(e,o){var n=g.get.elementCalculations(),t=g.get.screenCalculations();e=e||!1,e&&(p.continuous?(g.debug("Callback being called continuously",o,n),e.call(z,n,t)):g.get.occurred(o)||(g.debug("Conditions met",o,n),e.call(z,n,t))),g.save.occurred(o)},remove:{fixed:function(){g.debug("Removing fixed position"),V.removeClass(h.fixed).css({position:"",top:"",left:"",zIndex:""}),p.onUnfixed.call(z)},placeholder:function(){g.debug("Removing placeholder content"),s&&s.remove()},occurred:function(e){if(e){var o=g.cache.occurred;void 0!==o[e]&&!0===o[e]&&(g.debug("Callback can now be called again",e),g.cache.occurred[e]=!1)}else g.cache.occurred={}}},save:{calculations:function(){g.verbose("Saving all calculations necessary to determine positioning"),g.save.direction(),g.save.screenCalculations(),g.save.elementCalculations()},occurred:function(e){e&&(void 0!==g.cache.occurred[e]&&!0===g.cache.occurred[e]||(g.verbose("Saving callback occurred",e),g.cache.occurred[e]=!0))},scroll:function(e){e=e+p.offset||k.scrollTop()+p.offset,g.cache.scroll=e},direction:function(){var e,o=g.get.scroll(),n=g.get.lastScroll();return e=o>n&&n?"down":o<n&&n?"up":"static",g.cache.direction=e,g.cache.direction},elementPosition:function(){var e=g.cache.element,o=g.get.screenSize();return g.verbose("Saving element position"),e.fits=e.height<o.height,e.offset=V.offset(),e.width=V.outerWidth(),e.height=V.outerHeight(),g.is.verticallyScrollableContext()&&(e.offset.top+=k.scrollTop()-k.offset().top),g.is.horizontallyScrollableContext()&&(e.offset.left+=k.scrollLeft-k.offset().left),g.cache.element=e,e},elementCalculations:function(){var e=g.get.screenCalculations(),o=g.get.elementPosition();return p.includeMargin?(o.margin={},o.margin.top=parseInt(V.css("margin-top"),10),o.margin.bottom=parseInt(V.css("margin-bottom"),10),o.top=o.offset.top-o.margin.top,o.bottom=o.offset.top+o.height+o.margin.bottom):(o.top=o.offset.top,o.bottom=o.offset.top+o.height),o.topPassed=e.top>=o.top,o.bottomPassed=e.top>=o.bottom,o.topVisible=e.bottom>=o.top&&!o.bottomPassed,o.bottomVisible=e.bottom>=o.bottom&&!o.topPassed,o.pixelsPassed=0,o.percentagePassed=0,o.onScreen=o.topVisible&&!o.bottomPassed,o.passing=o.topPassed&&!o.bottomPassed,o.offScreen=!o.onScreen,o.passing&&(o.pixelsPassed=e.top-o.top,o.percentagePassed=(e.top-o.top)/o.height),g.cache.element=o,g.verbose("Updated element calculations",o),o},screenCalculations:function(){var e=g.get.scroll();return g.save.direction(),g.cache.screen.top=e,g.cache.screen.bottom=e+g.cache.screen.height,g.cache.screen},screenSize:function(){g.verbose("Saving window position"),g.cache.screen={height:k.height()}},position:function(){g.save.screenSize(),g.save.elementPosition()}},get:{pixelsPassed:function(e){var o=g.get.elementCalculations();return e.search("%")>-1?o.height*(parseInt(e,10)/100):parseInt(e,10)},occurred:function(e){return void 0!==g.cache.occurred&&(g.cache.occurred[e]||!1)},direction:function(){return void 0===g.cache.direction&&g.save.direction(),g.cache.direction},elementPosition:function(){return void 0===g.cache.element&&g.save.elementPosition(),g.cache.element},elementCalculations:function(){return void 0===g.cache.element&&g.save.elementCalculations(),g.cache.element},screenCalculations:function(){return void 0===g.cache.screen&&g.save.screenCalculations(),g.cache.screen},screenSize:function(){return void 0===g.cache.screen&&g.save.screenSize(),g.cache.screen},scroll:function(){return void 0===g.cache.scroll&&g.save.scroll(),g.cache.scroll},lastScroll:function(){return void 0===g.cache.screen?(g.debug("First scroll event, no last scroll could be found"),!1):g.cache.screen.top}},setting:function(o,n){if(e.isPlainObject(o))e.extend(!0,p,o);else{if(void 0===n)return p[o];p[o]=n}},internal:function(o,n){if(e.isPlainObject(o))e.extend(!0,g,o);else{if(void 0===n)return g[o];g[o]=n}},debug:function(){!p.silent&&p.debug&&(p.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,p.name+":"),g.debug.apply(console,arguments)))},verbose:function(){!p.silent&&p.verbose&&p.debug&&(p.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,p.name+":"),g.verbose.apply(console,arguments)))},error:function(){p.silent||(g.error=Function.prototype.bind.call(console.error,console,p.name+":"),g.error.apply(console,arguments))},performance:{log:function(e){var o,n,t;p.performance&&(o=(new Date).getTime(),t=r||o,n=o-t,r=o,a.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:z,"Execution Time":n})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,500)},display:function(){var o=p.name+":",n=0;r=!1,clearTimeout(g.performance.timer),e.each(a,function(e,o){n+=o["Execution Time"]}),o+=" "+n+"ms",c&&(o+=" '"+c+"'"),(void 0!==console.group||void 0!==console.table)&&a.length>0&&(console.groupCollapsed(o),console.table?console.table(a):e.each(a,function(e,o){console.log(o.Name+": "+o["Execution Time"]+"ms")}),console.groupEnd()),a=[]}},invoke:function(o,n,t){var s,c,r,a=T;return n=n||u,t=z||t,"string"==typeof o&&void 0!==a&&(o=o.split(/[\. ]/),s=o.length-1,e.each(o,function(n,t){var i=n!=s?t+o[n+1].charAt(0).toUpperCase()+o[n+1].slice(1):o;if(e.isPlainObject(a[i])&&n!=s)a=a[i];else{if(void 0!==a[i])return c=a[i],!1;if(!e.isPlainObject(a[t])||n==s)return void 0!==a[t]?(c=a[t],!1):(g.error(x.method,o),!1);a=a[t]}})),e.isFunction(c)?r=c.apply(t,n):void 0!==c&&(r=c),e.isArray(i)?i.push(r):void 0!==i?i=[i,r]:void 0!==r&&(i=r),c}},d?(void 0===T&&g.initialize(),T.save.scroll(),T.save.calculations(),g.invoke(l)):(void 0!==T&&T.invoke("destroy"),g.initialize())}),void 0!==i?i:this},e.fn.visibility.settings={name:"Visibility",namespace:"visibility",debug:!1,verbose:!1,performance:!0,observeChanges:!0,initialCheck:!0,refreshOnLoad:!0,refreshOnResize:!0,checkOnRefresh:!0,once:!0,continuous:!1,offset:0,includeMargin:!1,context:o,throttle:!1,type:!1,zIndex:"10",transition:"fade in",duration:1e3,onPassed:{},onOnScreen:!1,onOffScreen:!1,onPassing:!1,onTopVisible:!1,onBottomVisible:!1,onTopPassed:!1,onBottomPassed:!1,onPassingReverse:!1,onTopVisibleReverse:!1,onBottomVisibleReverse:!1,onTopPassedReverse:!1,onBottomPassedReverse:!1,onLoad:function(){},onAllLoaded:function(){},onFixed:function(){},onUnfixed:function(){},onUpdate:!1,onRefresh:function(){},metadata:{src:"src"},className:{fixed:"fixed",placeholder:"placeholder",visible:"visible"},error:{method:"The method you called is not defined.",visible:"Element is hidden, you must call refresh after element becomes visible"}}}(jQuery,window,document); |