wow.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. (function() {
  2. var MutationObserver, Util, WeakMap, getComputedStyle, getComputedStyleRX,
  3. __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  4. __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  5. Util = (function() {
  6. function Util() {}
  7. Util.prototype.extend = function(custom, defaults) {
  8. var key, value;
  9. for (key in defaults) {
  10. value = defaults[key];
  11. if (custom[key] == null) {
  12. custom[key] = value;
  13. }
  14. }
  15. return custom;
  16. };
  17. Util.prototype.isMobile = function(agent) {
  18. return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent);
  19. };
  20. Util.prototype.addEvent = function(elem, event, fn) {
  21. if (elem.addEventListener != null) {
  22. return elem.addEventListener(event, fn, false);
  23. } else if (elem.attachEvent != null) {
  24. return elem.attachEvent("on" + event, fn);
  25. } else {
  26. return elem[event] = fn;
  27. }
  28. };
  29. Util.prototype.removeEvent = function(elem, event, fn) {
  30. if (elem.removeEventListener != null) {
  31. return elem.removeEventListener(event, fn, false);
  32. } else if (elem.detachEvent != null) {
  33. return elem.detachEvent("on" + event, fn);
  34. } else {
  35. return delete elem[event];
  36. }
  37. };
  38. Util.prototype.innerHeight = function() {
  39. if ('innerHeight' in window) {
  40. return window.innerHeight;
  41. } else {
  42. return document.documentElement.clientHeight;
  43. }
  44. };
  45. return Util;
  46. })();
  47. WeakMap = this.WeakMap || this.MozWeakMap || (WeakMap = (function() {
  48. function WeakMap() {
  49. this.keys = [];
  50. this.values = [];
  51. }
  52. WeakMap.prototype.get = function(key) {
  53. var i, item, _i, _len, _ref;
  54. _ref = this.keys;
  55. for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
  56. item = _ref[i];
  57. if (item === key) {
  58. return this.values[i];
  59. }
  60. }
  61. };
  62. WeakMap.prototype.set = function(key, value) {
  63. var i, item, _i, _len, _ref;
  64. _ref = this.keys;
  65. for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
  66. item = _ref[i];
  67. if (item === key) {
  68. this.values[i] = value;
  69. return;
  70. }
  71. }
  72. this.keys.push(key);
  73. return this.values.push(value);
  74. };
  75. return WeakMap;
  76. })());
  77. MutationObserver = this.MutationObserver || this.WebkitMutationObserver || this.MozMutationObserver || (MutationObserver = (function() {
  78. function MutationObserver() {
  79. if (typeof console !== "undefined" && console !== null) {
  80. console.warn('MutationObserver is not supported by your browser.');
  81. }
  82. if (typeof console !== "undefined" && console !== null) {
  83. console.warn('WOW.js cannot detect dom mutations, please call .sync() after loading new content.');
  84. }
  85. }
  86. MutationObserver.notSupported = true;
  87. MutationObserver.prototype.observe = function() {};
  88. return MutationObserver;
  89. })());
  90. getComputedStyle = this.getComputedStyle || function(el, pseudo) {
  91. this.getPropertyValue = function(prop) {
  92. var _ref;
  93. if (prop === 'float') {
  94. prop = 'styleFloat';
  95. }
  96. if (getComputedStyleRX.test(prop)) {
  97. prop.replace(getComputedStyleRX, function(_, char) {
  98. return char.toUpperCase();
  99. });
  100. }
  101. return ((_ref = el.currentStyle) != null ? _ref[prop] : void 0) || null;
  102. };
  103. return this;
  104. };
  105. getComputedStyleRX = /(\-([a-z]){1})/g;
  106. this.WOW = (function() {
  107. WOW.prototype.defaults = {
  108. boxClass: 'wow',
  109. animateClass: 'animated',
  110. offset: 0,
  111. mobile: true,
  112. live: true
  113. };
  114. function WOW(options) {
  115. if (options == null) {
  116. options = {};
  117. }
  118. this.scrollCallback = __bind(this.scrollCallback, this);
  119. this.scrollHandler = __bind(this.scrollHandler, this);
  120. this.start = __bind(this.start, this);
  121. this.scrolled = true;
  122. this.config = this.util().extend(options, this.defaults);
  123. this.animationNameCache = new WeakMap();
  124. }
  125. WOW.prototype.init = function() {
  126. var _ref;
  127. this.element = window.document.documentElement;
  128. if ((_ref = document.readyState) === "interactive" || _ref === "complete") {
  129. this.start();
  130. } else {
  131. this.util().addEvent(document, 'DOMContentLoaded', this.start);
  132. }
  133. return this.finished = [];
  134. };
  135. WOW.prototype.start = function() {
  136. var box, _i, _len, _ref;
  137. this.stopped = false;
  138. this.boxes = (function() {
  139. var _i, _len, _ref, _results;
  140. _ref = this.element.querySelectorAll("." + this.config.boxClass);
  141. _results = [];
  142. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  143. box = _ref[_i];
  144. _results.push(box);
  145. }
  146. return _results;
  147. }).call(this);
  148. this.all = (function() {
  149. var _i, _len, _ref, _results;
  150. _ref = this.boxes;
  151. _results = [];
  152. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  153. box = _ref[_i];
  154. _results.push(box);
  155. }
  156. return _results;
  157. }).call(this);
  158. if (this.boxes.length) {
  159. if (this.disabled()) {
  160. this.resetStyle();
  161. } else {
  162. _ref = this.boxes;
  163. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  164. box = _ref[_i];
  165. this.applyStyle(box, true);
  166. }
  167. this.util().addEvent(window, 'scroll', this.scrollHandler);
  168. this.util().addEvent(window, 'resize', this.scrollHandler);
  169. this.interval = setInterval(this.scrollCallback, 50);
  170. }
  171. }
  172. if (this.config.live) {
  173. return new MutationObserver((function(_this) {
  174. return function(records) {
  175. var node, record, _j, _len1, _results;
  176. _results = [];
  177. for (_j = 0, _len1 = records.length; _j < _len1; _j++) {
  178. record = records[_j];
  179. _results.push((function() {
  180. var _k, _len2, _ref1, _results1;
  181. _ref1 = record.addedNodes || [];
  182. _results1 = [];
  183. for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
  184. node = _ref1[_k];
  185. _results1.push(this.doSync(node));
  186. }
  187. return _results1;
  188. }).call(_this));
  189. }
  190. return _results;
  191. };
  192. })(this)).observe(document.body, {
  193. childList: true,
  194. subtree: true
  195. });
  196. }
  197. };
  198. WOW.prototype.stop = function() {
  199. this.stopped = true;
  200. this.util().removeEvent(window, 'scroll', this.scrollHandler);
  201. this.util().removeEvent(window, 'resize', this.scrollHandler);
  202. if (this.interval != null) {
  203. return clearInterval(this.interval);
  204. }
  205. };
  206. WOW.prototype.sync = function(element) {
  207. if (MutationObserver.notSupported) {
  208. return this.doSync(this.element);
  209. }
  210. };
  211. WOW.prototype.doSync = function(element) {
  212. var box, _i, _len, _ref, _results;
  213. if (!this.stopped) {
  214. if (element == null) {
  215. element = this.element;
  216. }
  217. if (element.nodeType !== 1) {
  218. return;
  219. }
  220. element = element.parentNode || element;
  221. _ref = element.querySelectorAll("." + this.config.boxClass);
  222. _results = [];
  223. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  224. box = _ref[_i];
  225. if (__indexOf.call(this.all, box) < 0) {
  226. this.applyStyle(box, true);
  227. this.boxes.push(box);
  228. this.all.push(box);
  229. _results.push(this.scrolled = true);
  230. } else {
  231. _results.push(void 0);
  232. }
  233. }
  234. return _results;
  235. }
  236. };
  237. WOW.prototype.show = function(box) {
  238. this.applyStyle(box);
  239. return box.className = "" + box.className + " " + this.config.animateClass;
  240. };
  241. WOW.prototype.applyStyle = function(box, hidden) {
  242. var delay, duration, iteration;
  243. duration = box.getAttribute('data-wow-duration');
  244. delay = box.getAttribute('data-wow-delay');
  245. iteration = box.getAttribute('data-wow-iteration');
  246. return this.animate((function(_this) {
  247. return function() {
  248. return _this.customStyle(box, hidden, duration, delay, iteration);
  249. };
  250. })(this));
  251. };
  252. WOW.prototype.animate = (function() {
  253. if ('requestAnimationFrame' in window) {
  254. return function(callback) {
  255. return window.requestAnimationFrame(callback);
  256. };
  257. } else {
  258. return function(callback) {
  259. return callback();
  260. };
  261. }
  262. })();
  263. WOW.prototype.resetStyle = function() {
  264. var box, _i, _len, _ref, _results;
  265. _ref = this.boxes;
  266. _results = [];
  267. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  268. box = _ref[_i];
  269. _results.push(box.setAttribute('style', 'visibility: visible;'));
  270. }
  271. return _results;
  272. };
  273. WOW.prototype.customStyle = function(box, hidden, duration, delay, iteration) {
  274. if (hidden) {
  275. this.cacheAnimationName(box);
  276. }
  277. box.style.visibility = hidden ? 'hidden' : 'visible';
  278. if (duration) {
  279. this.vendorSet(box.style, {
  280. animationDuration: duration
  281. });
  282. }
  283. if (delay) {
  284. this.vendorSet(box.style, {
  285. animationDelay: delay
  286. });
  287. }
  288. if (iteration) {
  289. this.vendorSet(box.style, {
  290. animationIterationCount: iteration
  291. });
  292. }
  293. this.vendorSet(box.style, {
  294. animationName: hidden ? 'none' : this.cachedAnimationName(box)
  295. });
  296. return box;
  297. };
  298. WOW.prototype.vendors = ["moz", "webkit"];
  299. WOW.prototype.vendorSet = function(elem, properties) {
  300. var name, value, vendor, _results;
  301. _results = [];
  302. for (name in properties) {
  303. value = properties[name];
  304. elem["" + name] = value;
  305. _results.push((function() {
  306. var _i, _len, _ref, _results1;
  307. _ref = this.vendors;
  308. _results1 = [];
  309. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  310. vendor = _ref[_i];
  311. _results1.push(elem["" + vendor + (name.charAt(0).toUpperCase()) + (name.substr(1))] = value);
  312. }
  313. return _results1;
  314. }).call(this));
  315. }
  316. return _results;
  317. };
  318. WOW.prototype.vendorCSS = function(elem, property) {
  319. var result, style, vendor, _i, _len, _ref;
  320. style = getComputedStyle(elem);
  321. result = style.getPropertyCSSValue(property);
  322. _ref = this.vendors;
  323. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  324. vendor = _ref[_i];
  325. result = result || style.getPropertyCSSValue("-" + vendor + "-" + property);
  326. }
  327. return result;
  328. };
  329. WOW.prototype.animationName = function(box) {
  330. var animationName;
  331. try {
  332. animationName = this.vendorCSS(box, 'animation-name').cssText;
  333. } catch (_error) {
  334. animationName = getComputedStyle(box).getPropertyValue('animation-name');
  335. }
  336. if (animationName === 'none') {
  337. return '';
  338. } else {
  339. return animationName;
  340. }
  341. };
  342. WOW.prototype.cacheAnimationName = function(box) {
  343. return this.animationNameCache.set(box, this.animationName(box));
  344. };
  345. WOW.prototype.cachedAnimationName = function(box) {
  346. return this.animationNameCache.get(box);
  347. };
  348. WOW.prototype.scrollHandler = function() {
  349. return this.scrolled = true;
  350. };
  351. WOW.prototype.scrollCallback = function() {
  352. var box;
  353. if (this.scrolled) {
  354. this.scrolled = false;
  355. this.boxes = (function() {
  356. var _i, _len, _ref, _results;
  357. _ref = this.boxes;
  358. _results = [];
  359. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  360. box = _ref[_i];
  361. if (!(box)) {
  362. continue;
  363. }
  364. if (this.isVisible(box)) {
  365. this.show(box);
  366. continue;
  367. }
  368. _results.push(box);
  369. }
  370. return _results;
  371. }).call(this);
  372. if (!(this.boxes.length || this.config.live)) {
  373. return this.stop();
  374. }
  375. }
  376. };
  377. WOW.prototype.offsetTop = function(element) {
  378. var top;
  379. while (element.offsetTop === void 0) {
  380. element = element.parentNode;
  381. }
  382. top = element.offsetTop;
  383. while (element = element.offsetParent) {
  384. top += element.offsetTop;
  385. }
  386. return top;
  387. };
  388. WOW.prototype.isVisible = function(box) {
  389. var bottom, offset, top, viewBottom, viewTop;
  390. offset = box.getAttribute('data-wow-offset') || this.config.offset;
  391. viewTop = window.pageYOffset;
  392. viewBottom = viewTop + Math.min(this.element.clientHeight, this.util().innerHeight()) - offset;
  393. top = this.offsetTop(box);
  394. bottom = top + box.clientHeight;
  395. return top <= viewBottom && bottom >= viewTop;
  396. };
  397. WOW.prototype.util = function() {
  398. return this._util != null ? this._util : this._util = new Util();
  399. };
  400. WOW.prototype.disabled = function() {
  401. return !this.config.mobile && this.util().isMobile(navigator.userAgent);
  402. };
  403. return WOW;
  404. })();
  405. }).call(this);