wow.js 12 KB

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