Diligent web site
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

waypoints.js 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. // Generated by CoffeeScript 1.6.2
  2. /*
  3. jQuery Waypoints - v2.0.4
  4. Copyright (c) 2011-2014 Caleb Troughton
  5. Dual licensed under the MIT license and GPL license.
  6. https://github.com/imakewebthings/jquery-waypoints/blob/master/licenses.txt
  7. */
  8. (function() {
  9. var __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; },
  10. __slice = [].slice;
  11. (function(root, factory) {
  12. if (typeof define === 'function' && define.amd) {
  13. return define('waypoints', ['jquery'], function($) {
  14. return factory($, root);
  15. });
  16. } else {
  17. return factory(root.jQuery, root);
  18. }
  19. })(this, function($, window) {
  20. var $w, Context, Waypoint, allWaypoints, contextCounter, contextKey, contexts, isTouch, jQMethods, methods, resizeEvent, scrollEvent, waypointCounter, waypointKey, wp, wps;
  21. $w = $(window);
  22. isTouch = __indexOf.call(window, 'ontouchstart') >= 0;
  23. allWaypoints = {
  24. horizontal: {},
  25. vertical: {}
  26. };
  27. contextCounter = 1;
  28. contexts = {};
  29. contextKey = 'waypoints-context-id';
  30. resizeEvent = 'resize.waypoints';
  31. scrollEvent = 'scroll.waypoints';
  32. waypointCounter = 1;
  33. waypointKey = 'waypoints-waypoint-ids';
  34. wp = 'waypoint';
  35. wps = 'waypoints';
  36. Context = (function() {
  37. function Context($element) {
  38. var _this = this;
  39. this.$element = $element;
  40. this.element = $element[0];
  41. this.didResize = false;
  42. this.didScroll = false;
  43. this.id = 'context' + contextCounter++;
  44. this.oldScroll = {
  45. x: $element.scrollLeft(),
  46. y: $element.scrollTop()
  47. };
  48. this.waypoints = {
  49. horizontal: {},
  50. vertical: {}
  51. };
  52. this.element[contextKey] = this.id;
  53. contexts[this.id] = this;
  54. $element.bind(scrollEvent, function() {
  55. var scrollHandler;
  56. if (!(_this.didScroll || isTouch)) {
  57. _this.didScroll = true;
  58. scrollHandler = function() {
  59. _this.doScroll();
  60. return _this.didScroll = false;
  61. };
  62. return window.setTimeout(scrollHandler, $[wps].settings.scrollThrottle);
  63. }
  64. });
  65. $element.bind(resizeEvent, function() {
  66. var resizeHandler;
  67. if (!_this.didResize) {
  68. _this.didResize = true;
  69. resizeHandler = function() {
  70. $[wps]('refresh');
  71. return _this.didResize = false;
  72. };
  73. return window.setTimeout(resizeHandler, $[wps].settings.resizeThrottle);
  74. }
  75. });
  76. }
  77. Context.prototype.doScroll = function() {
  78. var axes,
  79. _this = this;
  80. axes = {
  81. horizontal: {
  82. newScroll: this.$element.scrollLeft(),
  83. oldScroll: this.oldScroll.x,
  84. forward: 'right',
  85. backward: 'left'
  86. },
  87. vertical: {
  88. newScroll: this.$element.scrollTop(),
  89. oldScroll: this.oldScroll.y,
  90. forward: 'down',
  91. backward: 'up'
  92. }
  93. };
  94. if (isTouch && (!axes.vertical.oldScroll || !axes.vertical.newScroll)) {
  95. $[wps]('refresh');
  96. }
  97. $.each(axes, function(aKey, axis) {
  98. var direction, isForward, triggered;
  99. triggered = [];
  100. isForward = axis.newScroll > axis.oldScroll;
  101. direction = isForward ? axis.forward : axis.backward;
  102. $.each(_this.waypoints[aKey], function(wKey, waypoint) {
  103. var _ref, _ref1;
  104. if ((axis.oldScroll < (_ref = waypoint.offset) && _ref <= axis.newScroll)) {
  105. return triggered.push(waypoint);
  106. } else if ((axis.newScroll < (_ref1 = waypoint.offset) && _ref1 <= axis.oldScroll)) {
  107. return triggered.push(waypoint);
  108. }
  109. });
  110. triggered.sort(function(a, b) {
  111. return a.offset - b.offset;
  112. });
  113. if (!isForward) {
  114. triggered.reverse();
  115. }
  116. return $.each(triggered, function(i, waypoint) {
  117. if (waypoint.options.continuous || i === triggered.length - 1) {
  118. return waypoint.trigger([direction]);
  119. }
  120. });
  121. });
  122. return this.oldScroll = {
  123. x: axes.horizontal.newScroll,
  124. y: axes.vertical.newScroll
  125. };
  126. };
  127. Context.prototype.refresh = function() {
  128. var axes, cOffset, isWin,
  129. _this = this;
  130. isWin = $.isWindow(this.element);
  131. cOffset = this.$element.offset();
  132. this.doScroll();
  133. axes = {
  134. horizontal: {
  135. contextOffset: isWin ? 0 : cOffset.left,
  136. contextScroll: isWin ? 0 : this.oldScroll.x,
  137. contextDimension: this.$element.width(),
  138. oldScroll: this.oldScroll.x,
  139. forward: 'right',
  140. backward: 'left',
  141. offsetProp: 'left'
  142. },
  143. vertical: {
  144. contextOffset: isWin ? 0 : cOffset.top,
  145. contextScroll: isWin ? 0 : this.oldScroll.y,
  146. contextDimension: isWin ? $[wps]('viewportHeight') : this.$element.height(),
  147. oldScroll: this.oldScroll.y,
  148. forward: 'down',
  149. backward: 'up',
  150. offsetProp: 'top'
  151. }
  152. };
  153. return $.each(axes, function(aKey, axis) {
  154. return $.each(_this.waypoints[aKey], function(i, waypoint) {
  155. var adjustment, elementOffset, oldOffset, _ref, _ref1;
  156. adjustment = waypoint.options.offset;
  157. oldOffset = waypoint.offset;
  158. elementOffset = $.isWindow(waypoint.element) ? 0 : waypoint.$element.offset()[axis.offsetProp];
  159. if ($.isFunction(adjustment)) {
  160. adjustment = adjustment.apply(waypoint.element);
  161. } else if (typeof adjustment === 'string') {
  162. adjustment = parseFloat(adjustment);
  163. if (waypoint.options.offset.indexOf('%') > -1) {
  164. adjustment = Math.ceil(axis.contextDimension * adjustment / 100);
  165. }
  166. }
  167. waypoint.offset = elementOffset - axis.contextOffset + axis.contextScroll - adjustment;
  168. if ((waypoint.options.onlyOnScroll && (oldOffset != null)) || !waypoint.enabled) {
  169. return;
  170. }
  171. if (oldOffset !== null && (oldOffset < (_ref = axis.oldScroll) && _ref <= waypoint.offset)) {
  172. return waypoint.trigger([axis.backward]);
  173. } else if (oldOffset !== null && (oldOffset > (_ref1 = axis.oldScroll) && _ref1 >= waypoint.offset)) {
  174. return waypoint.trigger([axis.forward]);
  175. } else if (oldOffset === null && axis.oldScroll >= waypoint.offset) {
  176. return waypoint.trigger([axis.forward]);
  177. }
  178. });
  179. });
  180. };
  181. Context.prototype.checkEmpty = function() {
  182. if ($.isEmptyObject(this.waypoints.horizontal) && $.isEmptyObject(this.waypoints.vertical)) {
  183. this.$element.unbind([resizeEvent, scrollEvent].join(' '));
  184. return delete contexts[this.id];
  185. }
  186. };
  187. return Context;
  188. })();
  189. Waypoint = (function() {
  190. function Waypoint($element, context, options) {
  191. var idList, _ref;
  192. options = $.extend({}, $.fn[wp].defaults, options);
  193. if (options.offset === 'bottom-in-view') {
  194. options.offset = function() {
  195. var contextHeight;
  196. contextHeight = $[wps]('viewportHeight');
  197. if (!$.isWindow(context.element)) {
  198. contextHeight = context.$element.height();
  199. }
  200. return contextHeight - $(this).outerHeight();
  201. };
  202. }
  203. this.$element = $element;
  204. this.element = $element[0];
  205. this.axis = options.horizontal ? 'horizontal' : 'vertical';
  206. this.callback = options.handler;
  207. this.context = context;
  208. this.enabled = options.enabled;
  209. this.id = 'waypoints' + waypointCounter++;
  210. this.offset = null;
  211. this.options = options;
  212. context.waypoints[this.axis][this.id] = this;
  213. allWaypoints[this.axis][this.id] = this;
  214. idList = (_ref = this.element[waypointKey]) != null ? _ref : [];
  215. idList.push(this.id);
  216. this.element[waypointKey] = idList;
  217. }
  218. Waypoint.prototype.trigger = function(args) {
  219. if (!this.enabled) {
  220. return;
  221. }
  222. if (this.callback != null) {
  223. this.callback.apply(this.element, args);
  224. }
  225. if (this.options.triggerOnce) {
  226. return this.destroy();
  227. }
  228. };
  229. Waypoint.prototype.disable = function() {
  230. return this.enabled = false;
  231. };
  232. Waypoint.prototype.enable = function() {
  233. this.context.refresh();
  234. return this.enabled = true;
  235. };
  236. Waypoint.prototype.destroy = function() {
  237. delete allWaypoints[this.axis][this.id];
  238. delete this.context.waypoints[this.axis][this.id];
  239. return this.context.checkEmpty();
  240. };
  241. Waypoint.getWaypointsByElement = function(element) {
  242. var all, ids;
  243. ids = element[waypointKey];
  244. if (!ids) {
  245. return [];
  246. }
  247. all = $.extend({}, allWaypoints.horizontal, allWaypoints.vertical);
  248. return $.map(ids, function(id) {
  249. return all[id];
  250. });
  251. };
  252. return Waypoint;
  253. })();
  254. methods = {
  255. init: function(f, options) {
  256. var _ref;
  257. if (options == null) {
  258. options = {};
  259. }
  260. if ((_ref = options.handler) == null) {
  261. options.handler = f;
  262. }
  263. this.each(function() {
  264. var $this, context, contextElement, _ref1;
  265. $this = $(this);
  266. contextElement = (_ref1 = options.context) != null ? _ref1 : $.fn[wp].defaults.context;
  267. if (!$.isWindow(contextElement)) {
  268. contextElement = $this.closest(contextElement);
  269. }
  270. contextElement = $(contextElement);
  271. context = contexts[contextElement[0][contextKey]];
  272. if (!context) {
  273. context = new Context(contextElement);
  274. }
  275. return new Waypoint($this, context, options);
  276. });
  277. $[wps]('refresh');
  278. return this;
  279. },
  280. disable: function() {
  281. return methods._invoke.call(this, 'disable');
  282. },
  283. enable: function() {
  284. return methods._invoke.call(this, 'enable');
  285. },
  286. destroy: function() {
  287. return methods._invoke.call(this, 'destroy');
  288. },
  289. prev: function(axis, selector) {
  290. return methods._traverse.call(this, axis, selector, function(stack, index, waypoints) {
  291. if (index > 0) {
  292. return stack.push(waypoints[index - 1]);
  293. }
  294. });
  295. },
  296. next: function(axis, selector) {
  297. return methods._traverse.call(this, axis, selector, function(stack, index, waypoints) {
  298. if (index < waypoints.length - 1) {
  299. return stack.push(waypoints[index + 1]);
  300. }
  301. });
  302. },
  303. _traverse: function(axis, selector, push) {
  304. var stack, waypoints;
  305. if (axis == null) {
  306. axis = 'vertical';
  307. }
  308. if (selector == null) {
  309. selector = window;
  310. }
  311. waypoints = jQMethods.aggregate(selector);
  312. stack = [];
  313. this.each(function() {
  314. var index;
  315. index = $.inArray(this, waypoints[axis]);
  316. return push(stack, index, waypoints[axis]);
  317. });
  318. return this.pushStack(stack);
  319. },
  320. _invoke: function(method) {
  321. this.each(function() {
  322. var waypoints;
  323. waypoints = Waypoint.getWaypointsByElement(this);
  324. return $.each(waypoints, function(i, waypoint) {
  325. waypoint[method]();
  326. return true;
  327. });
  328. });
  329. return this;
  330. }
  331. };
  332. $.fn[wp] = function() {
  333. var args, method;
  334. method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  335. if (methods[method]) {
  336. return methods[method].apply(this, args);
  337. } else if ($.isFunction(method)) {
  338. return methods.init.apply(this, arguments);
  339. } else if ($.isPlainObject(method)) {
  340. return methods.init.apply(this, [null, method]);
  341. } else if (!method) {
  342. return $.error("jQuery Waypoints needs a callback function or handler option.");
  343. } else {
  344. return $.error("The " + method + " method does not exist in jQuery Waypoints.");
  345. }
  346. };
  347. $.fn[wp].defaults = {
  348. context: window,
  349. continuous: true,
  350. enabled: true,
  351. horizontal: false,
  352. offset: 0,
  353. triggerOnce: false
  354. };
  355. jQMethods = {
  356. refresh: function() {
  357. return $.each(contexts, function(i, context) {
  358. return context.refresh();
  359. });
  360. },
  361. viewportHeight: function() {
  362. var _ref;
  363. return (_ref = window.innerHeight) != null ? _ref : $w.height();
  364. },
  365. aggregate: function(contextSelector) {
  366. var collection, waypoints, _ref;
  367. collection = allWaypoints;
  368. if (contextSelector) {
  369. collection = (_ref = contexts[$(contextSelector)[0][contextKey]]) != null ? _ref.waypoints : void 0;
  370. }
  371. if (!collection) {
  372. return [];
  373. }
  374. waypoints = {
  375. horizontal: [],
  376. vertical: []
  377. };
  378. $.each(waypoints, function(axis, arr) {
  379. $.each(collection[axis], function(key, waypoint) {
  380. return arr.push(waypoint);
  381. });
  382. arr.sort(function(a, b) {
  383. return a.offset - b.offset;
  384. });
  385. waypoints[axis] = $.map(arr, function(waypoint) {
  386. return waypoint.element;
  387. });
  388. return waypoints[axis] = $.unique(waypoints[axis]);
  389. });
  390. return waypoints;
  391. },
  392. above: function(contextSelector) {
  393. if (contextSelector == null) {
  394. contextSelector = window;
  395. }
  396. return jQMethods._filter(contextSelector, 'vertical', function(context, waypoint) {
  397. return waypoint.offset <= context.oldScroll.y;
  398. });
  399. },
  400. below: function(contextSelector) {
  401. if (contextSelector == null) {
  402. contextSelector = window;
  403. }
  404. return jQMethods._filter(contextSelector, 'vertical', function(context, waypoint) {
  405. return waypoint.offset > context.oldScroll.y;
  406. });
  407. },
  408. left: function(contextSelector) {
  409. if (contextSelector == null) {
  410. contextSelector = window;
  411. }
  412. return jQMethods._filter(contextSelector, 'horizontal', function(context, waypoint) {
  413. return waypoint.offset <= context.oldScroll.x;
  414. });
  415. },
  416. right: function(contextSelector) {
  417. if (contextSelector == null) {
  418. contextSelector = window;
  419. }
  420. return jQMethods._filter(contextSelector, 'horizontal', function(context, waypoint) {
  421. return waypoint.offset > context.oldScroll.x;
  422. });
  423. },
  424. enable: function() {
  425. return jQMethods._invoke('enable');
  426. },
  427. disable: function() {
  428. return jQMethods._invoke('disable');
  429. },
  430. destroy: function() {
  431. return jQMethods._invoke('destroy');
  432. },
  433. extendFn: function(methodName, f) {
  434. return methods[methodName] = f;
  435. },
  436. _invoke: function(method) {
  437. var waypoints;
  438. waypoints = $.extend({}, allWaypoints.vertical, allWaypoints.horizontal);
  439. return $.each(waypoints, function(key, waypoint) {
  440. waypoint[method]();
  441. return true;
  442. });
  443. },
  444. _filter: function(selector, axis, test) {
  445. var context, waypoints;
  446. context = contexts[$(selector)[0][contextKey]];
  447. if (!context) {
  448. return [];
  449. }
  450. waypoints = [];
  451. $.each(context.waypoints[axis], function(i, waypoint) {
  452. if (test(context, waypoint)) {
  453. return waypoints.push(waypoint);
  454. }
  455. });
  456. waypoints.sort(function(a, b) {
  457. return a.offset - b.offset;
  458. });
  459. return $.map(waypoints, function(waypoint) {
  460. return waypoint.element;
  461. });
  462. }
  463. };
  464. $[wps] = function() {
  465. var args, method;
  466. method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  467. if (jQMethods[method]) {
  468. return jQMethods[method].apply(null, args);
  469. } else {
  470. return jQMethods.aggregate.call(null, method);
  471. }
  472. };
  473. $[wps].settings = {
  474. resizeThrottle: 100,
  475. scrollThrottle: 30
  476. };
  477. return $w.load(function() {
  478. return $[wps]('refresh');
  479. });
  480. });
  481. }).call(this);