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