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.

11 lines
11 KiB

/*!
* # Semantic UI 2.1.6 - Sticky
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
!function(e,t,o,n){"use strict";e.fn.sticky=function(o){var i,s=e(this),r=s.selector||"",l=(new Date).getTime(),c=[],a=arguments[0],f="string"==typeof a,m=[].slice.call(arguments,1);return s.each(function(){var s,u,d,h,g=e.isPlainObject(o)?e.extend(!0,{},e.fn.sticky.settings,o):e.extend({},e.fn.sticky.settings),p=g.className,b=g.namespace,v=g.error,x="."+b,C="module-"+b,S=e(this),y=e(t),k=e(g.scrollContext),T=(S.selector||"",S.data(C)),z=t.requestAnimationFrame||t.mozRequestAnimationFrame||t.webkitRequestAnimationFrame||t.msRequestAnimationFrame||function(e){setTimeout(e,0)},w=this;h={initialize:function(){h.determineContainer(),h.determineContext(),h.verbose("Initializing sticky",g,s),h.save.positions(),h.checkErrors(),h.bind.events(),g.observeChanges&&h.observeChanges(),h.instantiate()},instantiate:function(){h.verbose("Storing instance of module",h),T=h,S.data(C,h)},destroy:function(){h.verbose("Destroying previous instance"),h.reset(),d&&d.disconnect(),y.off("load"+x,h.event.load).off("resize"+x,h.event.resize),k.off("scrollchange"+x,h.event.scrollchange),S.removeData(C)},observeChanges:function(){var e=u[0];"MutationObserver"in t&&(d=new MutationObserver(function(e){clearTimeout(h.timer),h.timer=setTimeout(function(){h.verbose("DOM tree modified, updating sticky menu",e),h.refresh()},100)}),d.observe(w,{childList:!0,subtree:!0}),d.observe(e,{childList:!0,subtree:!0}),h.debug("Setting up mutation observer",d))},determineContainer:function(){s=S.offsetParent()},determineContext:function(){return u=g.context?e(g.context):s,0===u.length?void h.error(v.invalidContext,g.context,S):void 0},checkErrors:function(){return h.is.hidden()&&h.error(v.visible,S),h.cache.element.height>h.cache.context.height?(h.reset(),void h.error(v.elementSize,S)):void 0},bind:{events:function(){y.on("load"+x,h.event.load).on("resize"+x,h.event.resize),k.off("scroll"+x).on("scroll"+x,h.event.scroll).on("scrollchange"+x,h.event.scrollchange)}},event:{load:function(){h.verbose("Page contents finished loading"),z(h.refresh)},resize:function(){h.verbose("Window resized"),z(h.refresh)},scroll:function(){z(function(){k.triggerHandler("scrollchange"+x,k.scrollTop())})},scrollchange:function(e,t){h.stick(t),g.onScroll.call(w)}},refresh:function(e){h.reset(),g.context||h.determineContext(),e&&h.determineContainer(),h.save.positions(),h.stick(),g.onReposition.call(w)},supports:{sticky:function(){var t=e("<div/>");t[0];return t.addClass(p.supported),t.css("position").match("sticky")}},save:{lastScroll:function(e){h.lastScroll=e},elementScroll:function(e){h.elementScroll=e},positions:function(){var e={height:k.height()},t={margin:{top:parseInt(S.css("margin-top"),10),bottom:parseInt(S.css("margin-bottom"),10)},offset:S.offset(),width:S.outerWidth(),height:S.outerHeight()},o={offset:u.offset(),height:u.outerHeight()};({height:s.outerHeight()});h.is.standardScroll()||(h.debug("Non-standard scroll. Removing scroll offset from element offset"),e.top=k.scrollTop(),e.left=k.scrollLeft(),t.offset.top+=e.top,o.offset.top+=e.top,t.offset.left+=e.left,o.offset.left+=e.left),h.cache={fits:t.height<e.height,scrollContext:{height:e.height},element:{margin:t.margin,top:t.offset.top-t.margin.top,left:t.offset.left,width:t.width,height:t.height,bottom:t.offset.top+t.height},context:{top:o.offset.top,height:o.height,bottom:o.offset.top+o.height}},h.set.containerSize(),h.set.size(),h.stick(),h.debug("Caching element positions",h.cache)}},get:{direction:function(e){var t="down";return e=e||k.scrollTop(),h.lastScroll!==n&&(h.lastScroll<e?t="down":h.lastScroll>e&&(t="up")),t},scrollChange:function(e){return e=e||k.scrollTop(),h.lastScroll?e-h.lastScroll:0},currentElementScroll:function(){return h.elementScroll?h.elementScroll:h.is.top()?Math.abs(parseInt(S.css("top"),10))||0:Math.abs(parseInt(S.css("bottom"),10))||0},elementScroll:function(e){e=e||k.scrollTop();var t=h.cache.element,o=h.cache.scrollContext,n=h.get.scrollChange(e),i=t.height-o.height+g.offset,s=h.get.currentElementScroll(),r=s+n;return s=h.cache.fits||0>r?0:r>i?i:r}},remove:{lastScroll:function(){delete h.lastScroll},elementScroll:function(e){delete h.elementScroll},offset:function(){S.css("margin-top","")}},set:{offset:function(){h.verbose("Setting offset on element",g.offset),S.css("margin-top",g.offset)},containerSize:function(){var e=s.get(0).tagName;"HTML"===e||"body"==e?h.determineContainer():Math.abs(s.outerHeight()-h.cache.context.height)>g.jitter&&(h.debug("Context has padding, specifying exact height for container",h.cache.context.height),s.css({height:h.cache.context.height}))},minimumSize:function(){var e=h.cache.element;s.css("min-height",e.height)},scroll:function(e){h.debug("Setting scroll on element",e),h.elementScroll!=e&&(h.is.top()&&S.css("bottom","").css("top",-e),h.is.bottom()&&S.css("top","").css("bottom",e))},size:function(){0!==h.cache.element.height&&0!==h.cache.element.width&&(w.style.setProperty("width",h.cache.element.width+"px","important"),w.style.setProperty("height",h.cache.element.height+"px","important"))}},is:{standardScroll:function(){return k[0]==t},top:function(){return S.hasClass(p.top)},bottom:function(){return S.hasClass(p.bottom)},initialPosition:function(){return!h.is.fixed()&&!h.is.bound()},hidden:function(){return!S.is(":visible")},bound:function(){return S.hasClass(p.bound)},fixed:function(){return S.hasClass(p.fixed)}},stick:function(e){var t=e||k.scrollTop(),o=h.cache,n=o.fits,i=o.element,s=o.scrollContext,r=o.context,l=h.is.bottom()&&g.pushing?g.bottomOffset:g.offset,e={top:t+l,bottom:t+l+s.height},c=(h.get.direction(e.top),n?0:h.get.elementScroll(e.top)),a=!n,f=0!==i.height;f&&(h.is.initialPosition()?e.top>=r.bottom?(h.debug("Initial element position is bottom of container"),h.bindBottom()):e.top>i.top&&(i.height+e.top-c>=r.bottom?(h.debug("Initial element position is bottom of container"),h.bindBottom()):(h.debug("Initial element position is fixed"),h.fixTop())):h.is.fixed()?h.is.top()?e.top<=i.top?(h.debug("Fixed element reached top of container"),h.setInitialPosition()):i.height+e.top-c>=r.bottom?(h.debug("Fixed element reached bottom of container"),h.bindBottom()):a&&(h.set.scroll(c),h.save.lastScroll(e.top),h.save.elementScroll(c)):h.is.bottom()&&(e.bottom-i.height<=i.top?(h.debug("Bottom fixed rail has reached top of container"),h.setInitialPosition()):e.bottom>=r.bottom?(h.debug("Bottom fixed rail has reached bottom of container"),h.bindBottom()):a&&(h.set.scroll(c),h.save.lastScroll(e.top),h.save.elementScroll(c))):h.is.bottom()&&(e.top<=i.top?(h.debug("Jumped from bottom fixed to top fixed, most likely used home/end button"),h.setInitialPosition()):g.pushing?h.is.bound()&&e.bottom<=r.bottom&&(h.debug("Fixing bottom attached element to bottom of browser."),h.fixBottom()):h.is.bound()&&e.top<=r.bottom-i.height&&(h.debug("Fixing bottom attached element to top of browser."),h.fixTop())))},bindTop:function(){h.debug("Binding element to top of parent container"),h.remove.offset(),S.css({left:"",top:"",marginBottom:""}).removeClass(p.fixed).removeClass(p.bottom).addClass(p.bound).addClass(p.top),g.onTop.call(w),g.onUnstick.call(w)},bindBottom:function(){h.debug("Binding element to bottom of parent container"),h.remove.offset(),S.css({left:"",top:""}).removeClass(p.fixed).removeClass(p.top).addClass(p.bound).addClass(p.bottom),g.onBottom.call(w),g.onUnstick.call(w)},setInitialPosition:function(){h.debug("Returning to initial position"),h.unfix(),h.unbind()},fixTop:function(){h.debug("Fixing element to top of page"),h.set.minimumSize(),h.set.offset(),S.css({left:h.cache.element.left,bottom:"",marginBottom:""}).removeClass(p.bound).removeClass(p.bottom).addClass(p.fixed).addClass(p.top),g.onStick.call(w)},fixBottom:function(){h.debug("Sticking element to bottom of page"),h.set.minimumSize(),h.set.offset(),S.css({left:h.cache.element.left,bottom:"",marginBottom:""}).removeClass(p.bound).removeClass(p.top).addClass(p.fixed).addClass(p.bottom),g.onStick.call(w)},unbind:function(){h.is.bound()&&(h.debug("Removing container bound position on element"),h.remove.offset(),S.removeClass(p.bound).removeClass(p.top).removeClass(p.bottom))},unfix:function(){h.is.fixed()&&(h.debug("Removing fixed position on element"),h.remove.offset(),S.removeClass(p.fixed).removeClass(p.top).removeClass(p.bottom),g.onUnstick.call(w))},reset:function(){h.debug("Reseting elements position"),h.unbind(),h.unfix(),h.resetCSS(),h.remove.offset(),h.remove.lastScroll()},resetCSS:function(){S.css({width:"",height:""}),s.css({height:""})},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,g,t);else{if(o===n)return g[t];g[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,h,t);else{if(o===n)return h[t];h[t]=o}},debug:function(){g.debug&&(g.performance?h.performance.log(arguments):(h.debug=Function.prototype.bind.call(console.info,console,g.name+":"),h.debug.apply(console,arguments)))},verbose:function(){g.verbose&&g.debug&&(g.performance?h.performance.log(arguments):(h.verbose=Function.prototype.bind.call(console.info,console,g.name+":"),h.verbose.apply(console,arguments)))},error:function(){h.error=Function.prototype.bind.call(console.error,console,g.name+":"),h.error.apply(console,arguments)},performance:{log:function(e){var t,o,n;g.performance&&(t=(new Date).getTime(),n=l||t,o=t-n,l=t,c.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:w,"Execution Time":o})),clearTimeout(h.performance.timer),h.performance.timer=setTimeout(h.performance.display,0)},display:function(){var t=g.name+":",o=0;l=!1,clearTimeout(h.performance.timer),e.each(c,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",r&&(t+=" '"+r+"'"),(console.group!==n||console.table!==n)&&c.length>0&&(console.groupCollapsed(t),console.table?console.table(c):e.each(c,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),c=[]}},invoke:function(t,o,s){var r,l,c,a=T;return o=o||m,s=w||s,"string"==typeof t&&a!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(a[s])&&o!=r)a=a[s];else{if(a[s]!==n)return l=a[s],!1;if(!e.isPlainObject(a[i])||o==r)return a[i]!==n?(l=a[i],!1):!1;a=a[i]}})),e.isFunction(l)?c=l.apply(s,o):l!==n&&(c=l),e.isArray(i)?i.push(c):i!==n?i=[i,c]:c!==n&&(i=c),l}},f?(T===n&&h.initialize(),h.invoke(a)):(T!==n&&T.invoke("destroy"),h.initialize())}),i!==n?i:this},e.fn.sticky.settings={name:"Sticky",namespace:"sticky",debug:!1,verbose:!0,performance:!0,pushing:!1,context:!1,scrollContext:t,offset:0,bottomOffset:0,jitter:5,observeChanges:!1,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);