foundation.magellan.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*jslint unparam: true, browser: true, indent: 2 */
  2. ;(function ($, window, document, undefined) {
  3. 'use strict';
  4. Foundation.libs.magellan = {
  5. name : 'magellan',
  6. version : '4.2.0',
  7. settings : {
  8. activeClass: 'active'
  9. },
  10. init : function (scope, method, options) {
  11. this.scope = scope || this.scope;
  12. Foundation.inherit(this, 'data_options');
  13. if (typeof method === 'object') {
  14. $.extend(true, this.settings, method);
  15. }
  16. if (typeof method != 'string') {
  17. if (!this.settings.init) {
  18. this.fixed_magellan = $("[data-magellan-expedition]");
  19. this.set_threshold();
  20. this.last_destination = $('[data-magellan-destination]').last();
  21. this.events();
  22. }
  23. return this.settings.init;
  24. } else {
  25. return this[method].call(this, options);
  26. }
  27. },
  28. events : function () {
  29. var self = this;
  30. $(this.scope).on('arrival.fndtn.magellan', '[data-magellan-arrival]', function (e) {
  31. var $destination = $(this),
  32. $expedition = $destination.closest('[data-magellan-expedition]'),
  33. activeClass = $expedition.attr('data-magellan-active-class')
  34. || self.settings.activeClass;
  35. $destination
  36. .closest('[data-magellan-expedition]')
  37. .find('[data-magellan-arrival]')
  38. .not($destination)
  39. .removeClass(activeClass);
  40. $destination.addClass(activeClass);
  41. });
  42. this.fixed_magellan
  43. .on('update-position.fndtn.magellan', function(){
  44. var $el = $(this);
  45. // $el.data("magellan-fixed-position","");
  46. // $el.data("magellan-top-offset", "");
  47. })
  48. .trigger('update-position');
  49. $(window)
  50. .on('resize.fndtn.magellan', function() {
  51. this.fixed_magellan.trigger('update-position');
  52. }.bind(this))
  53. .on('scroll.fndtn.magellan', function() {
  54. var windowScrollTop = $(window).scrollTop();
  55. self.fixed_magellan.each(function() {
  56. var $expedition = $(this);
  57. if (typeof $expedition.data('magellan-top-offset') === 'undefined') {
  58. $expedition.data('magellan-top-offset', $expedition.offset().top);
  59. }
  60. if (typeof $expedition.data('magellan-fixed-position') === 'undefined') {
  61. $expedition.data('magellan-fixed-position', false)
  62. }
  63. var fixed_position = (windowScrollTop + self.settings.threshold) > $expedition.data("magellan-top-offset");
  64. var attr = $expedition.attr('data-magellan-top-offset');
  65. if ($expedition.data("magellan-fixed-position") != fixed_position) {
  66. $expedition.data("magellan-fixed-position", fixed_position);
  67. if (fixed_position) {
  68. $expedition.css({position:"fixed", top:0});
  69. } else {
  70. $expedition.css({position:"", top:""});
  71. }
  72. if (fixed_position && typeof attr != 'undefined' && attr != false) {
  73. $expedition.css({position:"fixed", top:attr + "px"});
  74. }
  75. }
  76. });
  77. });
  78. if (this.last_destination.length > 0) {
  79. $(window).on('scroll.fndtn.magellan', function (e) {
  80. var windowScrollTop = $(window).scrollTop(),
  81. scrolltopPlusHeight = windowScrollTop + $(window).height(),
  82. lastDestinationTop = Math.ceil(self.last_destination.offset().top);
  83. $('[data-magellan-destination]').each(function () {
  84. var $destination = $(this),
  85. destination_name = $destination.attr('data-magellan-destination'),
  86. topOffset = $destination.offset().top - windowScrollTop;
  87. if (topOffset <= self.settings.threshold) {
  88. $("[data-magellan-arrival='" + destination_name + "']").trigger('arrival');
  89. }
  90. // In large screens we may hit the bottom of the page and dont reach the top of the last magellan-destination, so lets force it
  91. if (scrolltopPlusHeight >= $(self.scope).height() && lastDestinationTop > windowScrollTop && lastDestinationTop < scrolltopPlusHeight) {
  92. $('[data-magellan-arrival]').last().trigger('arrival');
  93. }
  94. });
  95. });
  96. }
  97. this.settings.init = true;
  98. },
  99. set_threshold : function () {
  100. if (!this.settings.threshold) {
  101. this.settings.threshold = (this.fixed_magellan.length > 0) ?
  102. this.outerHeight(this.fixed_magellan, true) : 0;
  103. }
  104. },
  105. off : function () {
  106. $(this.scope).off('.fndtn.magellan');
  107. },
  108. reflow : function () {}
  109. };
  110. }(Foundation.zj, this, this.document));