1/* appear.js 1.0.3 */ 2appear = (function(){ 3 'use strict'; 4 var scrollLastPos = null, scrollTimer = 0, scroll = {}; 5 6 function track(){ 7 var newPos = window.scrollY || window.pageYOffset; // pageYOffset for IE9 8 if ( scrollLastPos != null ){ 9 scroll.velocity = newPos - scrollLastPos; 10 scroll.delta = (scroll.velocity >= 0) ? scroll.velocity : (-1 * scroll.velocity); 11 12 } 13 scrollLastPos = newPos; 14 if(scrollTimer){ 15 clearTimeout(scrollTimer); 16 } 17 scrollTimer = setTimeout(function(){ 18 scrollLastPos = null; 19 }, 30); 20 } 21 addEventListener('scroll', track, false); 22 23 // determine if a given element (plus an additional "bounds" area around it) is in the viewport 24 function viewable(el, bounds){ 25 var rect = el.getBoundingClientRect(); 26 return ( 27 (rect.top + rect.height) >= 0 && 28 (rect.left + rect.width) >= 0 && 29 (rect.bottom - rect.height) <= ( (window.innerHeight || document.documentElement.clientHeight) + bounds) && 30 (rect.right - rect.width) <= ( (window.innerWidth || document.documentElement.clientWidth) + bounds) 31 ); 32 } 33 34 return function(obj){ 35 36 return (function(obj){ 37 var initd = false, elements = [], elementsLength, reappear = [], 38 appeared = 0, disappeared = 0, timer, deltaSet, opts = {}, done; 39 40 // handle debouncing a function for better performance on scroll 41 function debounce(fn, delay) { 42 return function () { 43 var self = this, args = arguments; 44 clearTimeout(timer); 45 46 timer = setTimeout(function () { 47 fn.apply(self, args); 48 }, delay); 49 }; 50 } 51 52 // called on scroll and resize event, so debounce the actual function that does 53 // the heavy work of determining if an item is viewable and then "appearing" it 54 function checkAppear() { 55 if(scroll.delta < opts.delta.speed) { 56 if(!deltaSet) { 57 deltaSet = true; 58 doCheckAppear(); 59 setTimeout(function(){ 60 deltaSet = false; 61 }, opts.delta.timeout); 62 } 63 } 64 (debounce(function() { 65 doCheckAppear(); 66 }, opts.debounce)()); 67 } 68 69 function begin() { 70 // initial appear check before any scroll or resize event 71 doCheckAppear(); 72 73 // add relevant listeners 74 addEventListener('scroll', checkAppear, false); 75 addEventListener('resize', checkAppear, false); 76 } 77 78 function end() { 79 elements = []; 80 if(timer) { 81 clearTimeout(timer); 82 } 83 removeListeners(); 84 } 85 86 function removeListeners() { 87 88 removeEventListener('scroll', checkAppear, false); 89 removeEventListener('resize', checkAppear, false); 90 } 91 92 function doCheckAppear() { 93 if(done) { 94 return; 95 } 96 97 elements.forEach(function(n, i){ 98 if(n && viewable(n, opts.bounds)) { 99 // only act if the element is eligible to reappear 100 if(reappear[i]) { 101 // mark this element as not eligible to appear 102 reappear[i] = false; 103 // increment the count of appeared items 104 appeared++; 105 106 // call the appear fn 107 if(opts.appear) { 108 opts.appear(n); 109 } 110 // if not tracking reappears or disappears, need to remove node here 111 if(!opts.disappear && !opts.reappear) { 112 // stop tracking this node, which is now viewable 113 elements[i] = null; 114 } 115 } 116 } else { 117 if(reappear[i] === false) { 118 if(opts.disappear) { 119 opts.disappear(n); 120 } 121 // increment the dissappeared count 122 disappeared++; 123 124 // if not tracking reappears, need to remove node here 125 if(!opts.reappear) { 126 // stop tracking this node, which is now viewable 127 elements[i] = null; 128 } 129 } 130 // element is out of view and eligible to be appeared again 131 reappear[i] = true; 132 } 133 }); 134 135 // remove listeners if all items have (re)appeared 136 if(!opts.reappear && (!opts.appear || opts.appear && appeared === elementsLength) && (!opts.disappear || opts.disappear && disappeared === elementsLength)) { 137 // ensure done is only called once (could be called from a trailing debounce/throttle) 138 done = true; 139 removeListeners(); 140 // all items have appeared, so call the done fn 141 if(opts.done){ 142 opts.done(); 143 } 144 } 145 } 146
147 function init() { 148 // make sure we only init once 149 if(initd) { 150 return; 151 } 152 initd = true; 153 154 // call the obj init fn 155 if(opts.init) { 156 opts.init(); 157 } 158 // get the elements to work with 159 var els; 160 if(typeof opts.elements === 'function') { 161 els = opts.elements(); 162 } else { 163 els = opts.elements; 164 } 165 if(els) { 166 // put elements into an array object to work with 167 elementsLength = els.length; 168 for(var i = 0; i < elementsLength; i += 1) { 169 elements.push(els[i]); 170 reappear.push(true); 171 } 172 begin(); 173 } 174 } 175 176 return function(obj) { 177 obj = obj || {}; 178 179 // assign the fn to execute when a node is visible 180 opts = { 181 // a function to be run when the dom is ready (allows for any setup work) 182 init: obj.init, 183 // either an array of elements or a function that will return an htmlCollection 184 elements: obj.elements, 185 // function to call when an element is "viewable", will be passed the element to work with 186 appear: obj.appear, 187 // function to call when an element is no longer "viewable", will be passed the element to work with 188 disappear: obj.disappear, 189 // function to call when all the elements have "appeared" 190 done: obj.done, 191 // keep tracking the elements 192 reappear: obj.reappear, 193 // the extra border around an element to make it viewable outside of the true viewport 194 bounds: obj.bounds || 0, 195 // the debounce timeout 196 debounce: obj.debounce || 50, 197 // appear.js will also check for items on continuous slow scrolling 198 // you can controll how slow the scrolling should be (deltaSpeed) 199 // and when it will check again (deltaTimeout) after it has inspected the dom/viewport; 200 delta: { 201 speed: obj.deltaSpeed || 50, 202 timeout: obj.deltaTimeout || 500 203 } 204 }; 205 206 // add an event listener to init when dom is ready 207 addEventListener('DOMContentLoaded', init, false); 208 209 var isIE10 = false; 210 if (Function('/*@cc_on return document.documentMode===10@*/')()){ 211 isIE10 = true; 212 } 213 var completeOrLoaded = document.readyState === 'complete' || document.readyState === 'loaded'; 214 215 // call init if document is ready to be worked with and we missed the event 216 if (isIE10) { 217 if (completeOrLoaded) { 218 init(); 219 } 220 } else { 221 if (completeOrLoaded || document.readyState === 'interactive') { 222 init(); 223 } 224 } 225 226 return { 227 // manually fire check for visibility of tracked elements 228 trigger: function trigger(){ 229 doCheckAppear(); 230 }, 231 // pause tracking of elements 232 pause: function pause(){ 233 removeListeners(); 234 }, 235 // resume tracking of elements after a pause 236 resume: function resume(){ 237 begin(); 238 }, 239 // provide a means to stop monitoring all elements 240 destroy: function destroy() { 241 end(); 242 } 243 }; 244 245 }; 246 }()(obj)); 247 }; 248}());
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.