appear.js (4379B)
1 /* 2 * jQuery.appear 3 * https://github.com/bas2k/jquery.appear/ 4 * http://code.google.com/p/jquery-appear/ 5 * http://bas2k.ru/ 6 * 7 * Copyright (c) 2009 Michael Hixson 8 * Copyright (c) 2012-2014 Alexander Brovikov 9 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) 10 */ 11 (function($) { 12 $.fn.appear = function(fn, options) { 13 14 var settings = $.extend({ 15 16 //arbitrary data to pass to fn 17 data: undefined, 18 19 //call fn only on the first appear? 20 one: true, 21 22 // X & Y accuracy 23 accX: 0, 24 accY: 0 25 26 }, options); 27 28 return this.each(function() { 29 30 var t = $(this); 31 32 //whether the element is currently visible 33 t.appeared = false; 34 35 if (!fn) { 36 37 //trigger the custom event 38 t.trigger('appear', settings.data); 39 return; 40 } 41 42 var w = $(window); 43 44 //fires the appear event when appropriate 45 var check = function() { 46 47 //is the element hidden? 48 if (!t.is(':visible')) { 49 50 //it became hidden 51 t.appeared = false; 52 return; 53 } 54 55 //is the element inside the visible window? 56 var a = w.scrollLeft(); 57 var b = w.scrollTop(); 58 var o = t.offset(); 59 var x = o.left; 60 var y = o.top; 61 62 var ax = settings.accX; 63 var ay = settings.accY; 64 var th = t.height(); 65 var wh = w.height(); 66 var tw = t.width(); 67 var ww = w.width(); 68 69 if (y + th + ay >= b && 70 y <= b + wh + ay && 71 x + tw + ax >= a && 72 x <= a + ww + ax) { 73 74 //trigger the custom event 75 if (!t.appeared) t.trigger('appear', settings.data); 76 77 } else { 78 79 //it scrolled out of view 80 t.appeared = false; 81 } 82 }; 83 84 //create a modified fn with some additional logic 85 var modifiedFn = function() { 86 87 //mark the element as visible 88 t.appeared = true; 89 90 //is this supposed to happen only once? 91 if (settings.one) { 92 93 //remove the check 94 w.unbind('scroll', check); 95 var i = $.inArray(check, $.fn.appear.checks); 96 if (i >= 0) $.fn.appear.checks.splice(i, 1); 97 } 98 99 //trigger the original fn 100 fn.apply(this, arguments); 101 }; 102 103 //bind the modified fn to the element 104 if (settings.one) t.one('appear', settings.data, modifiedFn); 105 else t.bind('appear', settings.data, modifiedFn); 106 107 //check whenever the window scrolls 108 w.scroll(check); 109 110 //check whenever the dom changes 111 $.fn.appear.checks.push(check); 112 113 //check now 114 (check)(); 115 }); 116 }; 117 118 //keep a queue of appearance checks 119 $.extend($.fn.appear, { 120 121 checks: [], 122 timeout: null, 123 124 //process the queue 125 checkAll: function() { 126 var length = $.fn.appear.checks.length; 127 if (length > 0) while (length--) ($.fn.appear.checks[length])(); 128 }, 129 130 //check the queue asynchronously 131 run: function() { 132 if ($.fn.appear.timeout) clearTimeout($.fn.appear.timeout); 133 $.fn.appear.timeout = setTimeout($.fn.appear.checkAll, 20); 134 } 135 }); 136 137 //run checks when these methods are called 138 $.each(['append', 'prepend', 'after', 'before', 'attr', 139 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 140 'remove', 'css', 'show', 'hide'], function(i, n) { 141 var old = $.fn[n]; 142 if (old) { 143 $.fn[n] = function() { 144 var r = old.apply(this, arguments); 145 $.fn.appear.run(); 146 return r; 147 } 148 } 149 }); 150 151 })(jQuery);