1/** 2 * author Remy Sharp 3 * url http://remysharp.com/2009/01/26/element-in-view-event-plugin/ 4 * fork https://github.com/zuk/jquery.inview 5 */ 6(function($) { 7 'use strict'; 8 9 function getScrollTop() { 10 return window.pageYOffset || 11 document.documentElement.scrollTop || 12 document.body.scrollTop; 13 } 14 15 function getViewportHeight() { 16 var height = window.innerHeight; // Safari, Opera 17 // if this is correct then return it. iPad has compat Mode, so will 18 // go into check clientHeight (which has the wrong value). 19 if (height) { 20 return height; 21 } 22 var mode = document.compatMode; 23 24 if ((mode || !$.support.boxModel)) { // IE, Gecko 25 height = (mode === 'CSS1Compat') ? 26 document.documentElement.clientHeight : // Standards 27 document.body.clientHeight; // Quirks 28 } 29 30 return height; 31 } 32 33 function offsetTop(debug) { 34 // Manually calculate offset rather than using jQuery's offset 35 // This works-around iOS < 4 on iPad giving incorrect value 36 // cf http://bugs.jquery.com/ticket/6446#comment:9 37 var curtop = 0; 38 for (var obj = debug; obj; obj = obj.offsetParent) { 39 curtop += obj.offsetTop; 40 } 41 return curtop; 42 } 43 44 function checkInView() { 45 var viewportTop = getScrollTop(), 46 viewportBottom = viewportTop + getViewportHeight(); 47 48 49 50 51 $('.inview').each(function() { 52 var $el = $(this), 53 elTop = offsetTop(this), 54 elHeight = $el.height(), 55 elBottom = elTop + elHeight, 56 wasInView = $el.data('inview') || false, 57 offset = $el.data('offset') || 0, 58 inView = elTop >= viewportTop && elBottom <= viewportBottom, 59 isBottomVisible = elBottom + offset >= viewportTop && elTop <= viewportTop, 60 isTopVisible = elTop - offset <= viewportBottom && elBottom >= viewportBottom, 61 inViewWithOffset = inView || isBottomVisible || isTopVisible || 62 (elTop <= viewportTop && elBottom >= viewportBottom), 63 isAllVisible = elTop - offset <= viewportTop && elBottom >= viewportBottom - getViewportHeight(); 64 65 66 67 if (inViewWithOffset) { 68 var visPart = (isTopVisible) ? 'top' : (isBottomVisible) ? 'bottom' : 'both'; 69 if(isAllVisible){ 70 var visPart = 'all'; 71 } 72 if (!wasInView || wasInView !== visPart) { 73 $el.data('inview', visPart); 74 $el.trigger('inview', [true, visPart]); 75 76 } 77 } else if (!inView && wasInView) { 78 $el.data('inview', false); 79 $el.trigger('inview', [false]); 80 81 } 82 }); 83 } 84 85 function createFunctionLimitedToOneExecutionPerDelay(fn, delay) { 86 var shouldRun = false; 87 var timer = null; 88 89 function runOncePerDelay() { 90 if (timer !== null) { 91 shouldRun = true; 92 return; 93 } 94 shouldRun = false; 95 fn(); 96 timer = setTimeout(function() { 97 timer = null; 98 if (shouldRun) { 99 runOncePerDelay(); 100 } 101 }, delay); 102 } 103 104 return runOncePerDelay; 105 } 106 107 // ready.inview kicks the event to pick up any elements already in view. 108 // note however, this only works if the plugin is included after the elements are bound to 'inview' 109 var runner = createFunctionLimitedToOneExecutionPerDelay(checkInView, 100); 110 $(window).on('checkInView.inview click.inview ready.inview scroll.inview resize.inview', runner); 111 112})(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.