1/*! 2* jQuery whenInView; version: 1.2.5 3* https://github.com/funkhaus/whenInView 4* Copyright (c) 2016 Funkhaus; MIT license 5*/ 6(function($) { 7 8 $.fn.whenInView = function(options, outCb) { 9 10 var inCallback, 11 outCallback, 12 $elems = this; 13 14 // if first param is 'clear', clear the given wheninview event or all wheninview events 15 if( options == 'clear' ){ 16 17 $elems.off( outCb ? ( outCb + '.wheninview' ) : 'enter.wheninview exit.wheninview' ); 18 return this; 19 20 } 21 22 // if first param is function, treat as inCallback 23 if (typeof options === 'function') { 24 inCallback = options; 25 options = {}; 26 } 27 28 // if second param is function, treat as outCallback 29 if (typeof outCb === 'function') 30 outCallback = outCb; 31 32 // Defaults 33 var settings = $.extend({ 34 className: 'element-in-view', 35 container: window, 36 elementIn: null, 37 elementOut: null, 38 topOffset: 0, 39 bottomOffset: 0, 40 staggerInterval: 0, 41 removeWhenOut: false, 42 RAF: true, // if true, the master scroll event will be wrapped in a requestAnimationFrame 43 fireAtStart: true 44 }, options); 45 46 // Prep enter-view callback 47 settings.elementIn = inCallback || settings.elementIn || function(){ 48 49 $(this).addClass(settings.className); 50 51 }; 52 // Add enter-view callback 53 $elems.on('enter.wheninview', settings.elementIn); 54 55 // Prep leave-view callback 56 settings.elementOut = outCallback || settings.elementOut || function($elems){ 57 if (settings.removeWhenOut) { 58 console.log($($($elems).get(0).target)); 59 60 $($($elems).get(0).target).removeClass( settings.className ); 61 } 62 }; 63 // Add leave-view callback 64 $elems.on('exit.wheninview', settings.elementOut); 65 66 // Save window dimensions 67 var winHeight = window.innerHeight || document.documentElement.clientHeight; 68 var sTop = $(settings.container).scrollTop(); 69 70 // set variables for a percetage offset 71 var percentOffsetTop = false; 72 var percentOffsetBottom = false; 73 74 // if top offset was set as a percentage... 75 if ( String(settings.topOffset).indexOf('%') > -1 ){ 76 77 // get the percentage as a float 78 percentOffsetTop = parseFloat( settings.topOffset.replace('%', '') / 100 ); 79 80 // find the pixel value of the offset 81 settings.topOffset = winHeight * percentOffsetTop; 82 83 } 84 85 // if bottom offset was set as a percentage... 86 if ( String(settings.bottomOffset).indexOf('%') > -1 ){ 87 88 // get the percentage as a float 89 percentOffsetBottom = parseFloat( settings.bottomOffset.replace('%', '') / 100 ); 90 91 // find the pixel value of the offset 92 settings.bottomOffset = winHeight * percentOffsetBottom; 93 94 } 95 96 // set top offset and height 97 var calculateOffsets = function(){ 98 99 $elems.each(function(){ 100 101 // measure rectangle 102 rect = this.getBoundingClientRect(); 103 104 // set data attributes 105 $(this).data('top', (rect.top + sTop)); 106 $(this).data('height', rect.height); 107 108 }); 109 110 }; 111 112 // Update window dimensions when necessary 113 $(window).resize(function() { 114 115 // set window height 116 winHeight = window.innerHeight || document.documentElement.clientHeight; 117 118 // recalculate top offset 119 if ( percentOffsetTop ) 120 settings.topOffset = winHeight * percentOffsetTop; 121 122 // recalculate bottom offset 123 if ( percentOffsetBottom ) 124 settings.bottomOffset = winHeight * percentOffsetBottom; 125 126 // recalculate offset as elements 127 calculateOffsets(); 128 129 // run visibility check 130 window.requestAnimationFrame(checkVisibility); 131 }); 132 133 // catch manual recalculation event 134 $(document).on('recalculate.wheninview', function(){ 135 136 // recalculate offset as elements 137 calculateOffsets(); 138 139 // run visibility check 140 window.requestAnimationFrame(checkVisibility); 141 }); 142 143 // function to check what's in view 144 var checkVisibility = function(){ 145 146 var topTrigger = sTop + settings.topOffset; 147 var bottomTrigger = sTop + winHeight - settings.bottomOffset; 148 149 // find all visible elements 150 var $incoming = $elems.filter(function(){ 151 var elTop = $(this).data('top'); 152 var elHeight = $(this).data('height'); 153 return (elTop + elHeight) > topTrigger && elTop < bottomTrigger && !this.inView; 154 }); 155 156 if ( $incoming.length ){ 157 158 // set inView props 159 $incoming.each(function(){ 160 this.inView = true; 161 }); 162 163 // Stagger the class additions (default stagger interval is 0, so no visible effect) 164 $incoming.each(function(i){ 165 var $elem = $(this); 166 167 if( settings.staggerInterval > 0 ){ 168 setTimeout(function(){ 169 // fire inView callback 170 $elem.trigger('enter.wheninview', $incoming); 171 }, i * settings.staggerInterval); 172 } else { 173 // fire inView callback 174 $elem.trigger('enter.wheninview', $incoming); 175 } 176 }); 177 178 } 179 180 // find all outgoing elements 181 var $outgoing = $elems.filter(function(){ 182 var elTop = $(this).data('top'); 183 var elHeight = $(this).data('height'); 184 return this.inView == true && ((elTop + elHeight) < topTrigger || elTop > bottomTrigger); 185 }); 186 187 if ( $outgoing.length ){ 188 189 // set inView props 190 $outgoing.each(function(){ 191 this.inView = false;
192 }); 193 194 // fire outgoing callback 195 $outgoing.trigger('exit.wheninview', $outgoing); 196 } 197 198 } 199 200 // name master scroll listener 201 var masterScrollListener = function(){ 202 sTop = $(settings.container).scrollTop(); 203 204 // fire callback 205 if ( settings.RAF ){ 206 window.requestAnimationFrame(checkVisibility); 207 } else { 208 checkVisibility(); 209 } 210 211 } 212 213 // set master scroll listener 214 $(settings.container).scroll(masterScrollListener); 215 216 calculateOffsets(); 217 218 // kick main functions 219 if( settings.fireAtStart ){ 220 checkVisibility(); 221 } 222 223 // return $elems 224 return this; 225 } 226 227}(jQuery));
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.