appear.js 4.1 KB

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