1;(function ($, window, document, undefined) { 2 3 $.widget("infortis.stickyheader", { 4 5 options: { 6 stickyThreshold: 770 7 , cartBlockSelector: '#minicart' 8 } 9 10 , isSticky: false 11 , isSuspended: false 12 , headerContainer: undefined 13 , stickyContainer: undefined 14 , compareBlock: undefined 15 , cartBlock: undefined 16 , navHolderBlock1: undefined 17 , navHolderBlock2: undefined 18 , stickyContainerOffsetTop: 55 //Position of the bottom edge of the sticky container relative to the viewport 19 , requiredRecalculation: false //Flag: required recalculation of the position of the bottom edge of the sticky container 20 21 , _create: function() { 22 this._initPlugin(); 23 } 24 25 , _initPlugin: function(customOptions) 26 { 27 var _self = this; 28 29 //Initialize plugin basic properties 30 this.headerContainer = this.element; 31 this.stickyContainer = $('.sticky-container'); //Important: by default it's the same element as headerContainer 32 this.compareBlock = $('#mini-compare'); 33 this.cartBlock = $(this.options.cartBlockSelector); 34 this.navHolderBlock1 = $('#nav-holder2'); //"#nav-holder1" is reserved for search box 35 this.navHolderBlock2 = $('#nav-holder3'); 36 this.cartMarkerRegular = $('#mini-cart-marker-regular'); 37 this.compareMarkerRegular = $('#mini-compare-marker-regular'); 38 39 //After initializing plugin basic properties 40 this.hookToActivatedDeactivated(); //Important: call before activateSticky is called 41 this.calculateStickyContainerOffsetTop(); 42 this.applySticky(); 43 this.hookToScroll(); 44 this.hookToResize(); 45 46 if (this.options.stickyThreshold > 0) 47 { 48 enquire.register('(max-width: ' + (this.options.stickyThreshold - 1) + 'px)', { 49 match: function() { 50 _self.suspendSticky(); 51 }, 52 unmatch: function() { 53 _self.unsuspendSticky(); 54 } 55 }); 56 } 57 58 } //end: _initPlugin 59 60 , calculateStickyContainerOffsetTop: function() 61 { 62 //Calculate the position of the bottom edge of the sticky container relative to the viewport 63 this.stickyContainerOffsetTop = this.stickyContainer.offset().top + this.stickyContainer.outerHeight(); 64 65 //Important: disable flag 66 this.requiredRecalculation = false; 67 } 68 69 , applySticky: function() 70 { 71 if (this.isSuspended) return; 72 73 //If recalculation required 74 if (this.requiredRecalculation) 75 { 76 //Important: recalculate only when header is not sticky 77 if (!this.isSticky) 78 { 79 this.calculateStickyContainerOffsetTop(); 80 } 81 } 82 83 var viewportOffsetTop = $(window).scrollTop(); 84 85 if (viewportOffsetTop > this.stickyContainerOffsetTop) 86 { 87 if (!this.isSticky) 88 { 89 this.activateSticky(); 90 } 91 } 92 else 93 { 94 if (this.isSticky) 95 { 96 this.deactivateSticky(); 97 } 98 } 99 } 100 101 , activateSticky: function() 102 { 103 var stickyContainerHeight = this.stickyContainer.outerHeight(); 104 var originalHeaderHeight = this.headerContainer.css('height'); 105 106 //Compensate the change of the header height after the sticky container was removed from its normal position 107 this.headerContainer.css('height', originalHeaderHeight); 108 109 //Important: trigger event just before making the header sticky 110 //this.print('trigger: activate-STICKY-header'); /// 111 $(document).trigger("activate-sticky-header"); 112 113 //Make the header sticky 114 this.headerContainer.addClass('sticky-header'); 115 this.isSticky = true; 116 117 //Effect 118 this.stickyContainer.css('margin-top', '-' + stickyContainerHeight + 'px').animate({'margin-top': '0'}, 200, 'easeOutCubic'); 119 //this.stickyContainer.css('opacity', '0').animate({'opacity': '1'}, 300, 'easeOutCubic'); 120 } 121 122 , deactivateSticky: function() 123 { 124 //Remove the compensation of the header height change 125 this.headerContainer.css('height', ''); 126 127 this.headerContainer.removeClass('sticky-header'); 128 this.isSticky = false;
129 130 //this.print('trigger: deactivate-STICKY-header'); /// 131 $(document).trigger("deactivate-sticky-header"); 132 } 133 134 , suspendSticky: function() 135 { 136 this.isSuspended = true; 137 138 //Deactivate sticky header. 139 //Important: call method only when sticky header is actually active. 140 if (this.isSticky) 141 { 142 this.deactivateSticky(); 143 } 144 } 145 146 , unsuspendSticky: function() 147 { 148 this.isSuspended = false; 149 150 //Activate sticky header. 151 //Important: call applySticky instead of activateSticky to check if activation is needed. 152 this.applySticky(); 153 } 154 155 , hookToScroll: function() 156 { 157 var _self = this; 158 159 $(window).on("scroll", function(e) { 160 _self.applySticky(); 161 }); //end: on event 162 } 163 164 , hookToScrollDeferred: function() 165 { 166 var _self = this; 167 168 var windowScrollTimeout; 169 $(window).on("scroll", function() { 170 clearTimeout(windowScrollTimeout); 171 windowScrollTimeout = setTimeout(function() { 172 _self.applySticky(); 173 }, 50); 174 }); //end: on event 175 } 176 177 , hookToResize: function() 178 { 179 var _self = this; 180 181 $(window).on('themeResize', function(e) { 182 183 //Require recalculation 184 _self.requiredRecalculation = true; 185 186 //Remove the compensation of the header height change 187 _self.headerContainer.css('height', ''); 188 }); //end: on event 189 } 190 191 , hookToActivatedDeactivated: function() 192 { 193 var _self = this; 194 195 //When sticky header was activated 196 $(document).on('activate-sticky-header', function(e) { 197 198 if (_self.cartBlock.parent().hasClass('nav-holder') === false) 199 { 200 _self.navHolderBlock1.prepend(_self.cartBlock); 201 _self.cartBlock.data('moved', true); 202 } 203 204 if (_self.compareBlock.parent().hasClass('nav-holder') === false) 205 { 206 _self.navHolderBlock2.prepend(_self.compareBlock); 207 _self.compareBlock.data('moved', true); 208 } 209 210 }); //end: on event 211 212 //When sticky header was deactivated 213 $(document).on('deactivate-sticky-header', function(e) { 214 215 // Move the block back to the regular position but only: 216 // - if the block was moved there dynamically by this script (block is marked with 'moved' data) 217 // - if the block is inside a holder 218 219 if (_self.cartBlock.data('moved') && _self.cartBlock.parent().hasClass('nav-holder') === true) 220 { 221 _self.cartMarkerRegular.after(_self.cartBlock); 222 } 223 224 if (_self.compareBlock.data('moved') && _self.compareBlock.parent().hasClass('nav-holder') === true) 225 { 226 _self.compareMarkerRegular.after(_self.compareBlock); 227 } 228 229 }); //end: on event 230 } 231 232 // , print: function(msg) { 233 // console.log(msg); 234 // } 235 236 }); //end: widget 237 238})(jQuery, window, document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.