main.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. jQuery(document).ready(function($){
  2. function morphDropdown( element ) {
  3. this.element = element;
  4. this.mainNavigation = this.element.find('.main-nav');
  5. this.mainNavigationItems = this.mainNavigation.find('.has-dropdown');
  6. this.dropdownList = this.element.find('.dropdown-list');
  7. this.dropdownWrappers = this.dropdownList.find('.dropdown');
  8. this.dropdownItems = this.dropdownList.find('.content');
  9. this.dropdownBg = this.dropdownList.find('.bg-layer');
  10. this.mq = this.checkMq();
  11. this.bindEvents();
  12. }
  13. morphDropdown.prototype.checkMq = function() {
  14. //check screen size
  15. var self = this;
  16. return window.getComputedStyle(self.element.get(0), '::before').getPropertyValue('content').replace(/'/g, "").replace(/"/g, "").split(', ');
  17. };
  18. morphDropdown.prototype.bindEvents = function() {
  19. var self = this;
  20. //hover over an item in the main navigation
  21. this.mainNavigationItems.mouseenter(function(event){
  22. //hover over one of the nav items -> show dropdown
  23. self.showDropdown($(this));
  24. }).mouseleave(function(){
  25. setTimeout(function(){
  26. //if not hovering over a nav item or a dropdown -> hide dropdown
  27. if( self.mainNavigation.find('.has-dropdown:hover').length == 0 && self.element.find('.dropdown-list:hover').length == 0 ) self.hideDropdown();
  28. }, 50);
  29. });
  30. //hover over the dropdown
  31. this.dropdownList.mouseleave(function(){
  32. setTimeout(function(){
  33. //if not hovering over a dropdown or a nav item -> hide dropdown
  34. (self.mainNavigation.find('.has-dropdown:hover').length == 0 && self.element.find('.dropdown-list:hover').length == 0 ) && self.hideDropdown();
  35. }, 50);
  36. });
  37. //click on an item in the main navigation -> open a dropdown on a touch device
  38. this.mainNavigationItems.on('touchstart', function(event){
  39. var selectedDropdown = self.dropdownList.find('#'+$(this).data('content'));
  40. if( !self.element.hasClass('is-dropdown-visible') || !selectedDropdown.hasClass('active') ) {
  41. event.preventDefault();
  42. self.showDropdown($(this));
  43. }
  44. });
  45. //on small screens, open navigation clicking on the menu icon
  46. this.element.on('click', '.nav-trigger', function(event){
  47. event.preventDefault();
  48. self.element.toggleClass('nav-open');
  49. });
  50. };
  51. morphDropdown.prototype.showDropdown = function(item) {
  52. this.mq = this.checkMq();
  53. if( this.mq == 'desktop') {
  54. var self = this;
  55. var selectedDropdown = this.dropdownList.find('#'+item.data('content')),
  56. selectedDropdownHeight = selectedDropdown.innerHeight(),
  57. selectedDropdownWidth = selectedDropdown.children('.content').innerWidth(),
  58. selectedDropdownLeft = item.offset().left + item.innerWidth()/2 - selectedDropdownWidth/2;
  59. //update dropdown position and size
  60. this.updateDropdown(selectedDropdown, parseInt(selectedDropdownHeight), selectedDropdownWidth, parseInt(selectedDropdownLeft));
  61. //add active class to the proper dropdown item
  62. this.element.find('.active').removeClass('active');
  63. selectedDropdown.addClass('active').removeClass('move-left move-right').prevAll().addClass('move-left').end().nextAll().addClass('move-right');
  64. item.addClass('active');
  65. //show the dropdown wrapper if not visible yet
  66. if( !this.element.hasClass('is-dropdown-visible') ) {
  67. setTimeout(function(){
  68. self.element.addClass('is-dropdown-visible');
  69. }, 10);
  70. }
  71. }
  72. };
  73. morphDropdown.prototype.updateDropdown = function(dropdownItem, height, width, left) {
  74. this.dropdownList.css({
  75. '-moz-transform': 'translateX(' + left + 'px)',
  76. '-webkit-transform': 'translateX(' + left + 'px)',
  77. '-ms-transform': 'translateX(' + left + 'px)',
  78. '-o-transform': 'translateX(' + left + 'px)',
  79. 'transform': 'translateX(' + left + 'px)',
  80. 'width': width+'px',
  81. 'height': height+'px'
  82. });
  83. this.dropdownBg.css({
  84. '-moz-transform': 'scaleX(' + width + ') scaleY(' + height + ')',
  85. '-webkit-transform': 'scaleX(' + width + ') scaleY(' + height + ')',
  86. '-ms-transform': 'scaleX(' + width + ') scaleY(' + height + ')',
  87. '-o-transform': 'scaleX(' + width + ') scaleY(' + height + ')',
  88. 'transform': 'scaleX(' + width + ') scaleY(' + height + ')'
  89. });
  90. };
  91. morphDropdown.prototype.hideDropdown = function() {
  92. this.mq = this.checkMq();
  93. if( this.mq == 'desktop') {
  94. this.element.removeClass('is-dropdown-visible').find('.active').removeClass('active').end().find('.move-left').removeClass('move-left').end().find('.move-right').removeClass('move-right');
  95. }
  96. };
  97. morphDropdown.prototype.resetDropdown = function() {
  98. this.mq = this.checkMq();
  99. if( this.mq == 'mobile') {
  100. this.dropdownList.removeAttr('style');
  101. }
  102. };
  103. var morphDropdowns = [];
  104. if( $('.cd-morph-dropdown').length > 0 ) {
  105. $('.cd-morph-dropdown').each(function(){
  106. //create a morphDropdown object for each .cd-morph-dropdown
  107. morphDropdowns.push(new morphDropdown($(this)));
  108. });
  109. var resizing = false;
  110. //on resize, reset dropdown style property
  111. updateDropdownPosition();
  112. $(window).on('resize', function(){
  113. if( !resizing ) {
  114. resizing = true;
  115. (!window.requestAnimationFrame) ? setTimeout(updateDropdownPosition, 300) : window.requestAnimationFrame(updateDropdownPosition);
  116. }
  117. });
  118. function updateDropdownPosition() {
  119. morphDropdowns.forEach(function(element){
  120. element.resetDropdown();
  121. });
  122. resizing = false;
  123. };
  124. }
  125. });