You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1 lines
9.0 KiB

!function(a,b,c,d){"use strict";a.fn.sticky=function(c){var e,f=a(this),g=f.selector||"",h=(new Date).getTime(),i=[],j=arguments[0],k="string"==typeof j,l=[].slice.call(arguments,1);return f.each(function(){var f,m,n,o=a.extend(!0,{},a.fn.sticky.settings,c),p=o.className,q=o.namespace,r=o.error,s="."+q,t="module-"+q,u=a(this),v=a(b),w=u.offsetParent(),x=a(o.scrollContext),y=(u.selector||"",u.data(t)),z=b.requestAnimationFrame||b.mozRequestAnimationFrame||b.webkitRequestAnimationFrame||b.msRequestAnimationFrame||function(a){setTimeout(a,0)},A=this;n={initialize:function(){return f=o.context?a(o.context):w,0===f.size()?void n.error(r.invalidContext,o.context,u):(n.verbose("Initializing sticky",o,w),n.save.positions(),n.is.hidden()&&n.error(r.visible,u),n.cache.element.height>n.cache.context.height?(n.reset(),void n.error(r.elementSize,u)):(v.on("resize"+s,n.event.resize),x.on("scroll"+s,n.event.scroll),n.observeChanges(),void n.instantiate()))},instantiate:function(){n.verbose("Storing instance of module",n),y=n,u.data(t,n)},destroy:function(){n.verbose("Destroying previous module"),n.reset(),v.off("resize"+s,n.event.resize),x.off("scroll"+s,n.event.scroll),u.removeData(t)},observeChanges:function(){var a=f[0];MutationObserver!==d&&(m=new MutationObserver(function(){clearTimeout(n.timer),n.timer=setTimeout(function(){n.verbose("DOM tree modified, updating sticky menu"),n.refresh()},200)}),m.observe(A,{childList:!0,subtree:!0}),m.observe(a,{childList:!0,subtree:!0}),n.debug("Setting up mutation observer",m))},event:{resize:function(){z(function(){n.refresh(),n.stick()})},scroll:function(){z(function(){n.stick(),a.proxy(o.onScroll,A)()})}},refresh:function(b){n.reset(),b&&(w=u.offsetParent()),n.save.positions(),n.stick(),a.proxy(o.onReposition,A)()},supports:{sticky:function(){{var b=a("<div/>");b.get()}return b.addClass(p.supported),b.css("position").match("sticky")}},save:{scroll:function(a){n.lastScroll=a},positions:function(){var a={height:v.height()},b={margin:{top:parseInt(u.css("margin-top"),10),bottom:parseInt(u.css("margin-bottom"),10)},offset:u.offset(),width:u.outerWidth(),height:u.outerHeight()},c={offset:f.offset(),height:f.outerHeight()};n.cache={fits:b.height<a.height,window:{height:a.height},element:{margin:b.margin,top:b.offset.top-b.margin.top,left:b.offset.left,width:b.width,height:b.height,bottom:b.offset.top+b.height},context:{top:c.offset.top,height:c.height,bottom:c.offset.top+c.height}},n.set.containerSize(),n.set.size(),n.stick(),n.debug("Caching element positions",n.cache)}},get:{direction:function(a){var b="down";return a=a||x.scrollTop(),n.lastScroll!==d&&(n.lastScroll<a?b="down":n.lastScroll>a&&(b="up")),b},scrollChange:function(a){return a=a||x.scrollTop(),n.lastScroll?a-n.lastScroll:0},currentElementScroll:function(){return n.is.top()?Math.abs(parseInt(u.css("top"),10))||0:Math.abs(parseInt(u.css("bottom"),10))||0},elementScroll:function(a){a=a||x.scrollTop();var b,c=n.cache.element,d=n.cache.window,e=n.get.scrollChange(a),f=c.height-d.height+o.offset,g=n.get.currentElementScroll(),h=g+e;return b=n.cache.fits||0>h?0:h>f?f:h}},remove:{offset:function(){u.css("margin-top","")}},set:{offset:function(){n.verbose("Setting offset on element",o.offset),u.css("margin-top",o.offset)},containerSize:function(){var a=w.get(0).tagName;"HTML"===a||"body"==a?w=u.offsetParent():(n.debug("Settings container size",n.cache.context.height),w.height(n.cache.context.height))},scroll:function(a){n.debug("Setting scroll on element",a),n.is.top()&&u.css("bottom","").css("top",-a),n.is.bottom()&&u.css("top","").css("bottom",a)},size:function(){0!==n.cache.element.height&&0!==n.cache.element.width&&u.css({width:n.cache.element.width,height:n.cache.element.height})}},is:{top:function(){return u.hasClass(p.top)},bottom:function(){return u.hasClass(p.bottom)},initialPosition:function(){return!n.is.fixed()&&!n.is.bound()},hidden:function(){return!u.is(":visible")},bound:function(){return u.hasClass(p.bound)},fixed:function(){return u.hasClass(p.fixed)}},stick:function(){var a=n.cache,b=a.fits,c=a.element,d=a.window,e=a.context,f={top:x.scrollTop()+o.offset,bottom:x.scrollTop()+o.offset+d.height},g=(n.get.direction(f.top),n.get.elementScroll(f.top)),h=!b,i=0!==c.height;n.save.scroll(f.top),i&&(n.is.initialPosition()?f.top>=c.top&&(n.debug("Element passed, fixing element to page"),n.fixTop()):n.is.fixed()?n.is.top()?f.top<c.top?(n.debug("Fixed element reached top of container"),n.setInitialPosition()):c.height+f.top-g>e.bottom?(n.debug("Fixed element reached bottom of container"),n.bindBottom()):h&&n.set.scroll(g):n.is.bottom()&&(f.bottom-c.height<c.top?(n.debug("Bottom fixed rail has reached top of container"),n.setInitialPosition()):f.bottom>e.bottom?(n.debug("Bottom fixed rail has reached bottom of container"),n.bindBottom()):h&&n.set.scroll(g)):n.is.bottom()&&n.is.bottom()&&(o.pushing?n.is.bound()&&f.bottom<e.bottom&&(n.debug("Fixing bottom attached element to bottom of browser."),n.fixBottom()):n.is.bound()&&f.top<e.bottom-c.height&&(n.debug("Fixing bottom attached element to top of browser."),n.fixTop())))},bindTop:function(){n.debug("Binding element to top of parent container"),n.remove.offset(),u.css("left","").css("top","").css("bottom","").removeClass(p.fixed).removeClass(p.bottom).addClass(p.bound).addClass(p.top),a.proxy(o.onTop,A)(),a.proxy(o.onUnstick,A)()},bindBottom:function(){n.debug("Binding element to bottom of parent container"),n.remove.offset(),u.css("left","").css("top","").css("bottom","").removeClass(p.fixed).removeClass(p.top).addClass(p.bound).addClass(p.bottom),a.proxy(o.onBottom,A)(),a.proxy(o.onUnstick,A)()},setInitialPosition:function(){n.unfix(),n.unbind()},fixTop:function(){n.debug("Fixing element to top of page"),n.set.offset(),u.css("left",n.cache.element.left).removeClass(p.bound).removeClass(p.bottom).addClass(p.fixed).addClass(p.top),a.proxy(o.onStick,A)()},fixBottom:function(){n.debug("Sticking element to bottom of page"),n.set.offset(),u.css("left",n.cache.element.left).removeClass(p.bound).removeClass(p.top).addClass(p.fixed).addClass(p.bottom),a.proxy(o.onStick,A)()},unbind:function(){n.debug("Removing absolute position on element"),n.remove.offset(),u.removeClass(p.bound).removeClass(p.top).removeClass(p.bottom)},unfix:function(){n.debug("Removing fixed position on element"),n.remove.offset(),u.removeClass(p.fixed).removeClass(p.top).removeClass(p.bottom),a.proxy(o.onUnstick,this)()},reset:function(){n.debug("Reseting elements position"),n.unbind(),n.unfix(),n.resetCSS()},resetCSS:function(){u.css({top:"",bottom:"",width:"",height:""}),w.css({height:""})},setting:function(b,c){if(a.isPlainObject(b))a.extend(!0,o,b);else{if(c===d)return o[b];o[b]=c}},internal:function(b,c){if(a.isPlainObject(b))a.extend(!0,n,b);else{if(c===d)return n[b];n[b]=c}},debug:function(){o.debug&&(o.performance?n.performance.log(arguments):(n.debug=Function.prototype.bind.call(console.info,console,o.name+":"),n.debug.apply(console,arguments)))},verbose:function(){o.verbose&&o.debug&&(o.performance?n.performance.log(arguments):(n.verbose=Function.prototype.bind.call(console.info,console,o.name+":"),n.verbose.apply(console,arguments)))},error:function(){n.error=Function.prototype.bind.call(console.error,console,o.name+":"),n.error.apply(console,arguments)},performance:{log:function(a){var b,c,d;o.performance&&(b=(new Date).getTime(),d=h||b,c=b-d,h=b,i.push({Name:a[0],Arguments:[].slice.call(a,1)||"",Element:A,"Execution Time":c})),clearTimeout(n.performance.timer),n.performance.timer=setTimeout(n.performance.display,0)},display:function(){var b=o.name+":",c=0;h=!1,clearTimeout(n.performance.timer),a.each(i,function(a,b){c+=b["Execution Time"]}),b+=" "+c+"ms",g&&(b+=" '"+g+"'"),(console.group!==d||console.table!==d)&&i.length>0&&(console.groupCollapsed(b),console.table?console.table(i):a.each(i,function(a,b){console.log(b.Name+": "+b["Execution Time"]+"ms")}),console.groupEnd()),i=[]}},invoke:function(b,c,f){var g,h,i,j=y;return c=c||l,f=A||f,"string"==typeof b&&j!==d&&(b=b.split(/[\. ]/),g=b.length-1,a.each(b,function(c,e){var f=c!=g?e+b[c+1].charAt(0).toUpperCase()+b[c+1].slice(1):b;if(a.isPlainObject(j[f])&&c!=g)j=j[f];else{if(j[f]!==d)return h=j[f],!1;if(!a.isPlainObject(j[e])||c==g)return j[e]!==d?(h=j[e],!1):!1;j=j[e]}})),a.isFunction(h)?i=h.apply(f,c):h!==d&&(i=h),a.isArray(e)?e.push(i):e!==d?e=[e,i]:i!==d&&(e=i),h}},k?(y===d&&n.initialize(),n.invoke(j)):(y!==d&&n.destroy(),n.initialize())}),e!==d?e:this},a.fn.sticky.settings={name:"Sticky",namespace:"sticky",debug:!1,verbose:!1,performance:!1,pushing:!1,context:!1,scrollContext:b,offset:0,onReposition:function(){},onScroll:function(){},onStick:function(){},onUnstick:function(){},onTop:function(){},onBottom:function(){},error:{container:"Sticky element must be inside a relative container",visible:"Element is hidden, you must call refresh after element becomes visible",method:"The method you called is not defined.",invalidContext:"Context specified does not exist",elementSize:"Sticky element is larger than its container, cannot create sticky."},className:{bound:"bound",fixed:"fixed",supported:"native",top:"top",bottom:"bottom"}}}(jQuery,window,document);