1;(function ($, window, document, undefined) { 2 'use strict'; 3 4 Foundation.libs['magellan-expedition'] = { 5 name : 'magellan-expedition', 6 7 version : '5.5.1', 8 9 settings : { 10 active_class : 'active', 11 threshold : 0, // pixels from the top of the expedition for it to become fixes 12 destination_threshold : 20, // pixels from the top of destination for it to be considered active 13 throttle_delay : 30, // calculation throttling to increase framerate 14 fixed_top : 0, // top distance in pixels assigend to the fixed element on scroll 15 offset_by_height : true, // whether to offset the destination by the expedition height. Usually you want this to be true, unless your expedition is on the side. 16 duration : 700, // animation duration time 17 easing : 'swing' // animation easing 18 }, 19 20 init : function (scope, method, options) { 21 Foundation.inherit(this, 'throttle'); 22 this.bindings(method, options); 23 }, 24 25 events : function () { 26 var self = this, 27 S = self.S, 28 settings = self.settings; 29 30 // initialize expedition offset 31 self.set_expedition_position(); 32 33 S(self.scope) 34 .off('.magellan') 35 .on('click.fndtn.magellan', '[' + self.add_namespace('data-magellan-arrival') + '] a[href^="#"]', function (e) { 36 e.preventDefault(); 37 var expedition = $(this).closest('[' + self.attr_name() + ']'), 38 settings = expedition.data('magellan-expedition-init'), 39 hash = this.hash.split('#').join(''), 40 target = $('a[name="' + hash + '"]'); 41 42 if (target.length === 0) { 43 target = $('#' + hash); 44 45 } 46 47 // Account for expedition height if fixed position 48 var scroll_top = target.offset().top - settings.destination_threshold + 1; 49 if (settings.offset_by_height) { 50 scroll_top = scroll_top - expedition.outerHeight(); 51 } 52 53 $('html, body').stop().animate({ 54 'scrollTop' : scroll_top 55 }, settings.duration, settings.easing, function () { 56 if (history.pushState) { 57 history.pushState(null, null, '#' + hash); 58 } else { 59 location.hash = '#' + hash; 60 } 61 }); 62 }) 63 .on('scroll.fndtn.magellan', self.throttle(this.check_for_arrivals.bind(this), settings.throttle_delay)); 64 65 $(window) 66 .on('resize.fndtn.magellan', self.throttle(this.set_expedition_position.bind(this), settings.throttle_delay)); 67 }, 68 69 check_for_arrivals : function () { 70 var self = this; 71 self.update_arrivals(); 72 self.update_expedition_positions(); 73 }, 74 75 set_expedition_position : function () { 76 var self = this; 77 $('[' + this.attr_name() + '=fixed]', self.scope).each(function (idx, el) { 78 var expedition = $(this), 79 settings = expedition.data('magellan-expedition-init'), 80 styles = expedition.attr('styles'), // save styles 81 top_offset, fixed_top; 82 83 expedition.attr('style', ''); 84 top_offset = expedition.offset().top + settings.threshold; 85 86 //set fixed-top by attribute 87 fixed_top = parseInt(expedition.data('magellan-fixed-top')); 88 if (!isNaN(fixed_top)) { 89 self.settings.fixed_top = fixed_top; 90 } 91 92 expedition.data(self.data_attr('magellan-top-offset'), top_offset); 93 expedition.attr('style', styles); 94 }); 95 }, 96 97 update_expedition_positions : function () { 98 var self = this, 99 window_top_offset = $(window).scrollTop(); 100 101 $('[' + this.attr_name() + '=fixed]', self.scope).each(function () { 102 var expedition = $(this), 103 settings = expedition.data('magellan-expedition-init'), 104 styles = expedition.attr('style'), // save styles 105 top_offset = expedition.data('magellan-top-offset'); 106 107 //scroll to the top distance 108 if (window_top_offset + self.settings.fixed_top >= top_offset) { 109 // Placeholder allows height calculations to be consistent even when 110 // appearing to switch between fixed/non-fixed placement 111 var placeholder = expedition.prev('[' + self.add_namespace('data-magellan-expedition-clone') + ']'); 112 if (placeholder.length === 0) { 113 placeholder = expedition.clone(); 114 placeholder.removeAttr(self.attr_name()); 115 placeholder.attr(self.add_namespace('data-magellan-expedition-clone'), ''); 116 expedition.before(placeholder); 117 } 118 expedition.css({position :'fixed', top : settings.fixed_top}).addClass('fixed'); 119 } else { 120 expedition.prev('[' + self.add_namespace('data-magellan-expedition-clone') + ']').remove(); 121 expedition.attr('style', styles).css('position', '').css('top', '').removeClass('fixed'); 122 } 123 }); 124 }, 125 126 update_arrivals : function () { 127 var self = this, 128 window_top_offset = $(window).scrollTop(); 129 130 $('[' + this.attr_name() + ']', self.scope).each(function () { 131 var expedition = $(this), 132 settings = expedition.data(self.attr_name(true) + '-init'), 133 offsets = self.offsets(expedition, window_top_offset), 134 arrivals = expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']'), 135 active_item = false; 136 offsets.each(function (idx, item) { 137 if (item.viewport_offset >= item.top_offset) { 138 var arrivals = expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']'); 139 arrivals.not(item.arrival).removeClass(settings.active_class); 140 item.arrival.addClass(settings.active_class); 141 active_item = true; 142 return true; 143 } 144 }); 145 146 if (!active_item) { 147 arrivals.removeClass(settings.active_class); 148 } 149 }); 150 }, 151 152 offsets : function (expedition, window_offset) { 153 var self = this, 154 settings = expedition.data(self.attr_name(true) + '-init'), 155 viewport_offset = window_offset; 156 157 return expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']').map(function (idx, el) { 158 var name = $(this).data(self.data_attr('magellan-arrival')), 159 dest = $('[' + self.add_namespace('data-magellan-destination') + '=' + name + ']'); 160 if (dest.length > 0) { 161 var top_offset = dest.offset().top - settings.destination_threshold; 162 if (settings.offset_by_height) { 163 top_offset = top_offset - expedition.outerHeight(); 164 } 165 top_offset = Math.floor(top_offset); 166 return { 167 destination : dest, 168 arrival : $(this), 169 top_offset : top_offset, 170 viewport_offset : viewport_offset 171 } 172 } 173 }).sort(function (a, b) { 174 if (a.top_offset < b.top_offset) { 175 return -1; 176 } 177 if (a.top_offset > b.top_offset) { 178 return 1; 179 } 180 return 0; 181 }); 182 }, 183 184 data_attr : function (str) { 185 if (this.namespace.length > 0) { 186 return this.namespace + '-' + str; 187 } 188 189 return str; 190 }, 191 192 off : function () { 193 this.S(this.scope).off('.magellan'); 194 this.S(window).off('.magellan'); 195 }, 196 197 reflow : function () { 198 var self = this; 199 // remove placeholder expeditions used for height calculation purposes 200 $('[' + self.add_namespace('data-magellan-expedition-clone') + ']', self.scope).remove(); 201 } 202 }; 203}(jQuery, window, 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.