wow.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. (function() {
  2. var Util,
  3. __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
  4. Util = (function() {
  5. function Util() {}
  6. Util.prototype.extend = function(custom, defaults) {
  7. var key, value;
  8. for (key in custom) {
  9. value = custom[key];
  10. if (value != null) {
  11. defaults[key] = value;
  12. }
  13. }
  14. return defaults;
  15. };
  16. Util.prototype.isMobile = function(agent) {
  17. return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent);
  18. };
  19. return Util;
  20. })();
  21. this.WOW = (function() {
  22. WOW.prototype.defaults = {
  23. boxClass: 'wow',
  24. animateClass: 'animated',
  25. offset: 0,
  26. mobile: true
  27. };
  28. function WOW(options) {
  29. if (options == null) {
  30. options = {};
  31. }
  32. this.scrollCallback = __bind(this.scrollCallback, this);
  33. this.scrollHandler = __bind(this.scrollHandler, this);
  34. this.start = __bind(this.start, this);
  35. this.scrolled = true;
  36. this.config = this.util().extend(options, this.defaults);
  37. }
  38. WOW.prototype.init = function() {
  39. var _ref;
  40. this.element = window.document.documentElement;
  41. this.boxes = this.element.getElementsByClassName(this.config.boxClass);
  42. if (this.boxes.length) {
  43. if (this.disabled()) {
  44. return this.resetStyle();
  45. } else {
  46. if ((_ref = document.readyState) === "interactive" || _ref === "complete") {
  47. return this.start();
  48. } else {
  49. return document.addEventListener('DOMContentLoaded', this.start);
  50. }
  51. }
  52. }
  53. };
  54. WOW.prototype.start = function() {
  55. var box, _i, _len, _ref;
  56. _ref = this.boxes;
  57. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  58. box = _ref[_i];
  59. this.applyStyle(box, true);
  60. }
  61. window.addEventListener('scroll', this.scrollHandler, false);
  62. window.addEventListener('resize', this.scrollHandler, false);
  63. return this.interval = setInterval(this.scrollCallback, 50);
  64. };
  65. WOW.prototype.stop = function() {
  66. window.removeEventListener('scroll', this.scrollHandler, false);
  67. window.removeEventListener('resize', this.scrollHandler, false);
  68. if (this.interval != null) {
  69. return clearInterval(this.interval);
  70. }
  71. };
  72. WOW.prototype.show = function(box) {
  73. this.applyStyle(box);
  74. return box.className = "" + box.className + " " + this.config.animateClass;
  75. };
  76. WOW.prototype.applyStyle = function(box, hidden) {
  77. var delay, duration, iteration;
  78. duration = box.getAttribute('data-wow-duration');
  79. delay = box.getAttribute('data-wow-delay');
  80. iteration = box.getAttribute('data-wow-iteration');
  81. return box.setAttribute('style', this.customStyle(hidden, duration, delay, iteration));
  82. };
  83. WOW.prototype.resetStyle = function() {
  84. var box, _i, _len, _ref, _results;
  85. _ref = this.boxes;
  86. _results = [];
  87. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  88. box = _ref[_i];
  89. _results.push(box.setAttribute('style', 'visibility: visible;'));
  90. }
  91. return _results;
  92. };
  93. WOW.prototype.customStyle = function(hidden, duration, delay, iteration) {
  94. var style;
  95. style = hidden ? "visibility: hidden; -webkit-animation-name: none; -moz-animation-name: none; animation-name: none;" : "visibility: visible;";
  96. if (duration) {
  97. style += "-webkit-animation-duration: " + duration + "; -moz-animation-duration: " + duration + "; animation-duration: " + duration + ";";
  98. }
  99. if (delay) {
  100. style += "-webkit-animation-delay: " + delay + "; -moz-animation-delay: " + delay + "; animation-delay: " + delay + ";";
  101. }
  102. if (iteration) {
  103. style += "-webkit-animation-iteration-count: " + iteration + "; -moz-animation-iteration-count: " + iteration + "; animation-iteration-count: " + iteration + ";";
  104. }
  105. return style;
  106. };
  107. WOW.prototype.scrollHandler = function() {
  108. return this.scrolled = true;
  109. };
  110. WOW.prototype.scrollCallback = function() {
  111. var box;
  112. if (this.scrolled) {
  113. this.scrolled = false;
  114. this.boxes = (function() {
  115. var _i, _len, _ref, _results;
  116. _ref = this.boxes;
  117. _results = [];
  118. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  119. box = _ref[_i];
  120. if (!(box)) {
  121. continue;
  122. }
  123. if (this.isVisible(box)) {
  124. this.show(box);
  125. continue;
  126. }
  127. _results.push(box);
  128. }
  129. return _results;
  130. }).call(this);
  131. if (!this.boxes.length) {
  132. return this.stop();
  133. }
  134. }
  135. };
  136. WOW.prototype.offsetTop = function(element) {
  137. var top;
  138. top = element.offsetTop;
  139. while (element = element.offsetParent) {
  140. top += element.offsetTop;
  141. }
  142. return top;
  143. };
  144. WOW.prototype.isVisible = function(box) {
  145. var bottom, offset, top, viewBottom, viewTop;
  146. offset = box.getAttribute('data-wow-offset') || this.config.offset;
  147. viewTop = window.pageYOffset;
  148. viewBottom = viewTop + this.element.clientHeight - offset;
  149. top = this.offsetTop(box);
  150. bottom = top + box.clientHeight;
  151. return top <= viewBottom && bottom >= viewTop;
  152. };
  153. WOW.prototype.util = function() {
  154. return this._util || (this._util = new Util());
  155. };
  156. WOW.prototype.disabled = function() {
  157. return this.config.mobile === false && this.util().isMobile(navigator.userAgent);
  158. };
  159. return WOW;
  160. })();
  161. }).call(this);