1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) : 3 typeof define === 'function' && define.amd ? define(['jquery'], factory) : 4 (factory(global.jQuery)); 5}(this, (function ($) { 'use strict'; 6 7$ = $ && $.hasOwnProperty('default') ? $['default'] : $; 8 9/** 10 * @author Mudit Ameta 11 * @license https://github.com/zeusdeux/isInViewport/blob/master/license.md MIT 12 */ 13 14// expose isInViewport as a custom pseudo-selector 15$.extend($.expr.pseudos || $.expr[':'], { 16 // if $.expr.createPseudo is available, use it 17 'in-viewport': $.expr.createPseudo 18 ? $.expr.createPseudo(function (argsString) { return function (currElement) { return isInViewport(currElement, getSelectorArgs(argsString)); }; }) 19 : function (currObj, index, meta) { return isInViewport(currObj, getSelectorArgs(meta[3])); } 20}); 21 22 23// expose isInViewport as a function too 24// this lets folks pass around actual objects as options (like custom viewport) 25// and doesn't tie 'em down to strings. It also prevents isInViewport from 26// having to look up and wrap the dom element corresponding to the viewport selector 27$.fn.isInViewport = function(options) { 28 return this.filter(function (i, el) { return isInViewport(el, options); }) 29}; 30 31$.fn.run = run; 32 33// lets you chain any arbitrary function or an array of functions and returns a jquery object 34function run(args) { 35 var this$1 = this; 36 37 if (arguments.length === 1 && typeof args === 'function') { 38 args = [args]; 39 } 40 41 if (!(args instanceof Array)) { 42 throw new SyntaxError('isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions') 43 } 44 45 args.forEach(function (arg) { 46 if (typeof arg !== 'function') { 47 console.warn('isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions'); 48 console.warn('isInViewport: Ignoring non-function values in array and moving on'); 49 } else { 50 [].slice.call(this$1).forEach(function (t) { return arg.call($(t)); }); 51 } 52 }); 53 54 return this 55} 56 57 58// gets the width of the scrollbar 59function getScrollbarWidth(viewport) { 60 // append a div that has 100% width to get true width of viewport 61 var el = $('<div></div>').css({ 62 width: '100%' 63 }); 64 viewport.append(el); 65 66 // subtract true width from the viewport width which is inclusive 67 // of scrollbar by default 68 var scrollBarWidth = viewport.width() - el.width(); 69 70 // remove our element from DOM 71 el.remove(); 72 return scrollBarWidth 73} 74 75 76// Returns true if DOM element `element` is in viewport 77function isInViewport(element, options) { 78 var ref = element.getBoundingClientRect(); 79 var top = ref.top; 80 var bottom = ref.bottom; 81 var left = ref.left; 82 var right = ref.right; 83 84 var settings = $.extend({ 85 tolerance: 0, 86 viewport: window 87 }, options); 88 var isVisibleFlag = false; 89 var $viewport = settings.viewport.jquery ? settings.viewport : $(settings.viewport); 90 91 if (!$viewport.length) { 92 console.warn('isInViewport: The viewport selector you have provided matches no element on page.'); 93 console.warn('isInViewport: Defaulting to viewport as window'); 94 $viewport = $(window); 95 } 96 97 var $viewportHeight = $viewport.height(); 98 var $viewportWidth = $viewport.width(); 99 var typeofViewport = $viewport[0].toString(); 100 101 // if the viewport is other than window recalculate the top, 102 // bottom,left and right wrt the new viewport 103 // the [object DOMWindow] check is for window object type in PhantomJS 104 if ($viewport[0] !== window && typeofViewport !== '[object Window]' && typeofViewport !== '[object DOMWindow]') { 105 // use getBoundingClientRect() instead of $.Offset() 106 // since the original top/bottom positions are calculated relative to browser viewport and not document 107 var viewportRect = $viewport[0].getBoundingClientRect(); 108 109 // recalculate these relative to viewport 110 top = top - viewportRect.top; 111 bottom = bottom - viewportRect.top; 112 left = left - viewportRect.left; 113 right = right - viewportRect.left; 114 115 // get the scrollbar width from cache or calculate it 116 isInViewport.scrollBarWidth = isInViewport.scrollBarWidth || getScrollbarWidth($viewport); 117 118 // remove the width of the scrollbar from the viewport width 119 $viewportWidth -= isInViewport.scrollBarWidth; 120 } 121 122 // handle falsy, non-number and non-integer tolerance value 123 // same as checking using isNaN and then setting to 0 124 // bitwise operators deserve some love too you know 125 settings.tolerance = ~~Math.round(parseFloat(settings.tolerance)); 126 127 if (settings.tolerance < 0) {
128 settings.tolerance = $viewportHeight + settings.tolerance; // viewport height - tol 129 } 130 131 // the element is NOT in viewport iff it is completely out of 132 // viewport laterally or if it is completely out of the tolerance 133 // region. Therefore, if it is partially in view then it is considered 134 // to be in the viewport and hence true is returned. Because we have adjusted 135 // the left/right positions relative to the viewport, we should check the 136 // element's right against the viewport's 0 (left side), and the element's 137 // left against the viewport's width to see if it is outside of the viewport. 138 139 if (right <= 0 || left >= $viewportWidth) { 140 return isVisibleFlag 141 } 142 143 // if the element is bound to some tolerance 144 isVisibleFlag = settings.tolerance ? top <= settings.tolerance && bottom >= settings.tolerance : bottom > 0 && top <= $viewportHeight; 145 146 return isVisibleFlag 147} 148 149 150// get the selector args from the args string proved by Sizzle 151function getSelectorArgs(argsString) { 152 if (argsString) { 153 var args = argsString.split(','); 154 155 // when user only gives viewport and no tolerance 156 if (args.length === 1 && isNaN(args[0])) { 157 args[1] = args[0]; 158 args[0] = void 0; 159 } 160 161 return { 162 tolerance: args[0] ? args[0].trim() : void 0, 163 viewport: args[1] ? $(args[1].trim()) : void 0 164 } 165 } 166 return {} 167} 168 169}))); 170 171//# sourceMappingURL=isinviewport.js.map
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.