jquery.appear.js 3.1 KB

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