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