1/* 2 The MIT License (MIT) 3 4 Copyright (c) 2014 Dirk Groenen 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy of 7 this software and associated documentation files (the "Software"), to deal in 8 the Software without restriction, including without limitation the rights to 9 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 the Software, and to permit persons to whom the Software is furnished to do so, 11 subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in all 14 copies or substantial portions of the Software. 15*/ 16 17(function($){ 18 $.fn.viewportChecker = function(useroptions){ 19 // Define options and extend with user 20 var options = { 21 classToAdd: 'visible', 22 classToRemove : 'invisible', 23 classToAddForFullView : 'full-visible', 24 removeClassAfterAnimation: false, 25 offset: 100, 26 repeat: false, 27 invertBottomOffset: true, 28 callbackFunction: function(elem, action){}, 29 scrollHorizontal: false, 30 scrollBox: window 31 }; 32 $.extend(options, useroptions); 33 34 // Cache the given element and height of the browser 35 var $elem = this, 36 boxSize = {height: $(options.scrollBox).height(), width: $(options.scrollBox).width()}; 37 38 /* 39 * Main method that checks the elements and adds or removes the class(es) 40 */ 41 this.checkElements = function(){ 42 var viewportStart, viewportEnd; 43 44 // Set some vars to check with 45 if (!options.scrollHorizontal){ 46 viewportStart = Math.max( 47 $('html').scrollTop(), 48 $('body').scrollTop(), 49 $(window).scrollTop() 50 ); 51 viewportEnd = (viewportStart + boxSize.height); 52 } 53 else{ 54 viewportStart = Math.max( 55 $('html').scrollLeft(), 56 $('body').scrollLeft(), 57 $(window).scrollLeft() 58 ); 59 viewportEnd = (viewportStart + boxSize.width); 60 } 61 62 // Loop through all given dom elements 63 $elem.each(function(){ 64 var $obj = $(this), 65 objOptions = {}, 66 attrOptions = {}; 67 68 // Get any individual attribution data 69 if ($obj.data('vp-add-class')) 70 attrOptions.classToAdd = $obj.data('vp-add-class'); 71 if ($obj.data('vp-remove-class')) 72 attrOptions.classToRemove = $obj.data('vp-remove-class'); 73 if ($obj.data('vp-add-class-full-view')) 74 attrOptions.classToAddForFullView = $obj.data('vp-add-class-full-view'); 75 if ($obj.data('vp-keep-add-class')) 76 attrOptions.removeClassAfterAnimation = $obj.data('vp-remove-after-animation'); 77 if ($obj.data('vp-offset')) 78 attrOptions.offset = $obj.data('vp-offset'); 79 if ($obj.data('vp-repeat')) 80 attrOptions.repeat = $obj.data('vp-repeat'); 81 if ($obj.data('vp-scrollHorizontal')) 82 attrOptions.scrollHorizontal = $obj.data('vp-scrollHorizontal'); 83 if ($obj.data('vp-invertBottomOffset')) 84 attrOptions.scrollHorizontal = $obj.data('vp-invertBottomOffset'); 85 86 // Extend objOptions with data attributes and default options 87 $.extend(objOptions, options); 88 $.extend(objOptions, attrOptions); 89 90 // If class already exists; quit 91 if ($obj.data('vp-animated') && !objOptions.repeat){ 92 return; 93 } 94 95 // Check if the offset is percentage based 96 if (String(objOptions.offset).indexOf("%") > 0) 97 objOptions.offset = (parseInt(objOptions.offset) / 100) * boxSize.height; 98 99 // Get the raw start and end positions 100 var rawStart = (!objOptions.scrollHorizontal) ? $obj.offset().top : $obj.offset().left, 101 rawEnd = (!objOptions.scrollHorizontal) ? rawStart + $obj.height() : rawStart + $obj.width(); 102 103 // Add the defined offset 104 var elemStart = Math.round( rawStart ) + objOptions.offset, 105 elemEnd = (!objOptions.scrollHorizontal) ? elemStart + $obj.height() : elemStart + $obj.width(); 106 107 if (objOptions.invertBottomOffset) 108 elemEnd -= (objOptions.offset * 2); 109 110 // Add class if in viewport 111 if ((elemStart < viewportEnd) && (elemEnd > viewportStart)){ 112 113 // Remove class 114 $obj.removeClass(objOptions.classToRemove); 115 $obj.addClass(objOptions.classToAdd); 116 117 // Do the callback function. Callback wil send the jQuery object as parameter 118 objOptions.callbackFunction($obj, "add"); 119 120 // Check if full element is in view 121 if (rawEnd <= viewportEnd && rawStart >= viewportStart) 122 $obj.addClass(objOptions.classToAddForFullView); 123 else 124 $obj.removeClass(objOptions.classToAddForFullView); 125 126 // Set element as already animated 127 $obj.data('vp-animated', true); 128 129 if (objOptions.removeClassAfterAnimation) { 130 $obj.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){ 131 $obj.removeClass(objOptions.classToAdd); 132 }); 133 } 134 135 // Remove class if not in viewport and repeat is true 136 } else if ($obj.hasClass(objOptions.classToAdd) && (objOptions.repeat)){ 137 $obj.removeClass(objOptions.classToAdd + " " + objOptions.classToAddForFullView); 138 139 // Do the callback function. 140 objOptions.callbackFunction($obj, "remove"); 141 142 // Remove already-animated-flag 143 $obj.data('vp-animated', false); 144 } 145 }); 146 147 }; 148 149 /** 150 * Binding the correct event listener is still a tricky thing. 151 * People have expierenced sloppy scrolling when both scroll and touch 152 * events are added, but to make sure devices with both scroll and touch 153 * are handles too we always have to add the window.scroll event 154 *
155 * @see https://github.com/dirkgroenen/jQuery-viewport-checker/issues/25 156 * @see https://github.com/dirkgroenen/jQuery-viewport-checker/issues/27 157 */ 158 159 // Select the correct events 160 if( 'ontouchstart' in window || 'onmsgesturechange' in window ){ 161 // Device with touchscreen 162 $(document).bind("touchmove MSPointerMove pointermove", this.checkElements); 163 } 164 165 // Always load on window load 166 $(options.scrollBox).bind("load scroll", this.checkElements); 167 168 // On resize change the height var 169 $(window).resize(function(e){ 170 boxSize = {height: $(options.scrollBox).height(), width: $(options.scrollBox).width()}; 171 $elem.checkElements(); 172 }); 173 174 // trigger inital check if elements already visible 175 this.checkElements(); 176 177 // Default jquery plugin behaviour 178 return this; 179 }; 180})(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.