doghouse_menu-3.0.x-dev/js/src/Menu.js

js/src/Menu.js
let $ = jQuery;


function whichTransitionEvent(){
  var t;
  var el = document.createElement('fakeelement');
  var animEndEventNames = {
    'WebkitAnimation' : 'webkitAnimationEnd',
    'OAnimation' : 'oAnimationEnd',
    'msAnimation' : 'MSAnimationEnd',
    'animation' : 'animationend'
  };

  for(t in animEndEventNames){
    if( el.style[t] !== undefined ){
      return animEndEventNames[t];
    }
  }
}

function onEndAnimation( el, callback ) {
  var animationEvent = whichTransitionEvent();
  var onEndCallbackFn = function( ev ) {
    if( ev.target != this ) {
      return;
    }
    this.removeEventListener( animationEvent, onEndCallbackFn );
    if( callback && typeof callback === 'function' ) {
      callback.call();
    }
  };
  el.addEventListener( animationEvent, onEndCallbackFn);
};

class SlideMenu {
  constructor(options) {
    this.options = Object.assign(this.defaults, options);
    this.$el = this.options.el;
    this.menus = this.$el.find(`.${this.options.classes.level}`);
    this.links = this.$el.find(`.${this.options.classes.link}`);
    this.nav = this.$el.find(`.${this.options.classes.nav}`)
    this.activeTree = [
      {
        name: 'All',
        link: 'main'
      }
    ];
    let $current = $('[data-menu="main"]').addClass(`${this.options.classes.level}--current`);
    $(`.${this.options.classes.wrap}`).height($current.height())
    this.clickListener();
    this.addNavHandler();
  }

  clickListener() {
    var self = this;
    this.links.click(function(e) {
      if( self.isAnimating ) {
        return false;
      }

      var $clicked = $(this);
      var $level = $clicked.closest(`.${self.options.classes.level}`);
      var pos = $level.find('.menu__link').index($clicked);

      var submenu = $clicked.attr('data-submenu');
      var $submenu = $("[data-menu='" + submenu + "']");
      var name = $clicked.text();

      if ($submenu.length) {
        e.preventDefault();
        self.isAnimating = true;
        self.slideOut(pos);
        self.slideIn($submenu, pos);
        self.updateTree(name, submenu);
      }

    });
  }

  slideOut(clickPosition, back = false) {
    var self = this;
    var $currentMenu = $(`.${this.options.classes.level}--current`);
    var $menuItems = $currentMenu.find(`.${this.options.classes.item}`);
    $menuItems.each(function(index, item) {
      var delay = parseInt(Math.abs(clickPosition - index) * self.options.itemsDelayInterval) + 'ms';
      $(item).css({
        'WebkitAnimationDelay': delay,
        'animationDelay': delay
      });
    });

    if( !back ) {
      $currentMenu.addClass(self.options.classes.AnimateOutLeft);
    }
    else {
      $currentMenu.addClass(self.options.classes.AnimateOutRight);
    }
  }

  slideIn($submenu, clickPosition, back = false) {
    var self = this;
    var $menuItems = $submenu.find(`.${this.options.classes.item}`);
    var menuItemsTotal = $menuItems.length;
    var $currentMenu = $(`.${this.options.classes.level}--current`);
    $(`.${this.options.classes.wrap}`).height($submenu.height())

    $menuItems.each(function(index, item) {
      var delay = parseInt(Math.abs(clickPosition - index) * self.options.itemsDelayInterval) + 'ms';
      $(item).css({
        'WebkitAnimationDelay': delay,
        'animationDelay': delay
      });

      var farthestIdx = clickPosition <= menuItemsTotal/2 ? menuItemsTotal - 1 : 0;

      if( index === farthestIdx ) {
        onEndAnimation(item, function() {
          if( !back ) {
            $currentMenu.removeClass(self.options.classes.AnimateOutLeft);
            $submenu.removeClass(self.options.classes.AnimateInRight);
          }
          else {
            $currentMenu.removeClass(self.options.classes.AnimateOutRight);
            $submenu.removeClass(self.options.classes.AnimateInLeft);
          }
          $currentMenu.removeClass(`${self.options.classes.level}--current`);
          $submenu.addClass(`${self.options.classes.level}--current`);
          self.isAnimating = false;
        });
      }
    });

    if( !back ) {
      $submenu.addClass(self.options.classes.AnimateInRight);
    }
    else {
      $submenu.addClass(self.options.classes.AnimateInLeft);
    }

  }

  addCrumb(name, link) {
    this.activeTree.push({
      name: name,
      link: link,
    });
    this.updateCrumbs();
  }

  updateTree(name, link) {
    this.activeTree.push({
      name: name,
      link: link,
    });
    this.nav.attr('data-active-tree', this.activeTree.length - 1);
  }

  addNavHandler() {
    var self = this;
    self.nav.click(function(e) {
      if (self.isAnimating) {
        return false;
      }
      if (self.activeTree.length > 1) {
        var i = self.activeTree.length - 2;
        var $submenu = $('[data-menu="' + self.activeTree[i].link + '"]');
        self.isAnimating = true;
        self.slideOut(0, true);
        self.slideIn($submenu, 0, true);
        self.activeTree.length -= 1;
        self.nav.attr('data-active-tree', self.activeTree.length - 1);
      }
    });
  }

  updateCrumbs() {
    var self = this;
    var $crumbs = $('.doghouse-menu__breadcrumbs');
    var html = this.activeTree.map(function(crumb){
      var link = $('<a>').attr('data-crumbmenu', crumb.link).text(crumb.name);
      return link;
    });
    html.forEach(function(v, i) {
      $(v).click(function(e) {
        if (i == html.length - 1 || self.isAnimating) {
          return false;
        }
        self.activeTree.length = i+1;
        var $submenu = $('[data-menu="' + self.activeTree[i].link + '"]');
        self.slideOut(0, true);
        self.slideIn($submenu, 0, true);
        self.updateCrumbs();
      });
    });
    $crumbs.html(html);

  }

}

SlideMenu.prototype.defaults = {
  itemsDelayInterval : 60,
  classes: {
    level: 'doghouse-menu__level',
    item: 'doghouse-menu__item',
    link: 'doghouse-menu__link',
    nav: 'doghouse-menu__nav',
    wrap: 'doghouse-menu__wrap',
    AnimateInLeft: 'doghouse-menu-animate--in-left',
    AnimateOutLeft: 'doghouse-menu-animate--out-left',
    AnimateInRight: 'doghouse-menu-animate--in-right',
    AnimateOutRight: 'doghouse-menu-animate--out-right',
  }
};

class AccordionMenu {
  constructor(options) {
    this.options = Object.assign(this.defaults, options);
    this.$el = this.options.el;

    $('.toggle', this.$el).click(function(e) {
      $(this)
        .toggleClass('open')
        .next('.menu').slideToggle()
    })

  }
}

AccordionMenu.prototype.defaults = {};

export {
  SlideMenu,
  AccordionMenu
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc