-2

I'm building a side nav with JavaScript ES6 and I started with the Supercharged-Show code example. I made a toggle button to replace the show and the hide ones. I try to use my toggleSideNav function to call the showSideNav but nothing happen. I'm probably missing something with the this.

My HTML page looks like this :

<body>
  <header class="header">
    <!--<button class="js-menu-show header__menu-toggle material-icons">menu</button>-->
    <hc-hamburger role="button" class="js-menu">
      <div class="hamburger-menu">
        <div class="bar"></div>
      </div>
    </hc-hamburger>
  </header>

  <aside class="js-side-nav side-nav">
    <nav class="js-side-nav-container side-nav__container">
      <!--<button class="js-menu-hide side-nav__hide material-icons">close</button>-->
      <header class="side-nav__header">
        Side Nav
      </header>
      <ul class="side-nav__content">
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
        <li>Four</li>
      </ul>
    </nav>
  </aside>
  <script src='./detabinator.js'></script>
  <script src='./side-nav.js'></script>
  <script src='./hamburger.js'></script>
</body>

And my JS file like this :

'use strict';

class SideNav {
  constructor () {
    this.toggleMenuEl = document.querySelector('.js-menu');
    this.showButtonEl = document.querySelector('.js-menu-show');
    this.hideButtonEl = document.querySelector('.js-menu-hide');
    this.sideNavEl = document.querySelector('.js-side-nav');
    this.sideNavContainerEl = document.querySelector('.js-side-nav-container');
    // Control whether the container's children can be focused
    // Set initial state to inert since the drawer is offscreen
    this.detabinator = new Detabinator(this.sideNavContainerEl);
    this.detabinator.inert = true;

    this.toggleSideNav = this.toggleSideNav.bind(this);
    this.showSideNav = this.showSideNav.bind(this);
    this.hideSideNav = this.hideSideNav.bind(this);
    this.blockClicks = this.blockClicks.bind(this);
    this.onTouchStart = this.onTouchStart.bind(this);
    this.onTouchMove = this.onTouchMove.bind(this);
    this.onTouchEnd = this.onTouchEnd.bind(this);
    this.onTransitionEnd = this.onTransitionEnd.bind(this);
    this.update = this.update.bind(this);

    this.startX = 0;
    this.currentX = 0;
    this.touchingSideNav = false;

    this.supportsPassive = undefined;
    this.addEventListeners();
  }

  // apply passive event listening if it's supported
  applyPassive () {
    if (this.supportsPassive !== undefined) {
      return this.supportsPassive ? {passive: true} : false;
    }
    // feature detect
    let isSupported = false;
    try {
      document.addEventListener('test', null, {get passive () {
        isSupported = true;
      }});
    } catch (e) { }
    this.supportsPassive = isSupported;
    return this.applyPassive();
  }

  addEventListeners () {
    this.toggleMenuEl.addEventListener('click', this.toggleSideNav);
    // this.showButtonEl.addEventListener('click', this.showSideNav);
    // this.hideButtonEl.addEventListener('click', this.hideSideNav);
    this.sideNavEl.addEventListener('click', this.hideSideNav);
    this.sideNavContainerEl.addEventListener('click', this.blockClicks);

    this.sideNavEl.addEventListener('touchstart', this.onTouchStart, this.applyPassive());
    this.sideNavEl.addEventListener('touchmove', this.onTouchMove, this.applyPassive());
    this.sideNavEl.addEventListener('touchend', this.onTouchEnd);
  }

  onTouchStart (evt) {
    if (!this.sideNavEl.classList.contains('side-nav--visible'))
      return;

    this.startX = evt.touches[0].pageX;
    this.currentX = this.startX;

    this.touchingSideNav = true;
    requestAnimationFrame(this.update);
  }

  onTouchMove (evt) {
    if (!this.touchingSideNav)
      return;

    this.currentX = evt.touches[0].pageX;
    const translateX = Math.min(0, this.currentX - this.startX);

    if (translateX < 0) {
      evt.preventDefault();
    }
  }

  onTouchEnd (evt) {
    if (!this.touchingSideNav)
      return;

    this.touchingSideNav = false;

    const translateX = Math.min(0, this.currentX - this.startX);
    this.sideNavContainerEl.style.transform = '';

    if (translateX < 0) {
      this.hideSideNav();
    }
  }

  update () {
    if (!this.touchingSideNav)
      return;

    requestAnimationFrame(this.update);

    const translateX = Math.min(0, this.currentX - this.startX);
    this.sideNavContainerEl.style.transform = `translateX(${translateX}px)`;
  }

  blockClicks (evt) {
    evt.stopPropagation();
  }

  onTransitionEnd (evt) {
    this.sideNavEl.classList.remove('side-nav--animatable');
    this.sideNavEl.removeEventListener('transitionend', this.onTransitionEnd);
  }

  showSideNav () {
    console.log('toto');
    this.sideNavEl.classList.add('side-nav--animatable');
    this.sideNavEl.classList.add('side-nav--visible');
    this.detabinator.inert = false;
    this.sideNavEl.addEventListener('transitionend', this.onTransitionEnd);
  }

  hideSideNav () {
    this.sideNavEl.classList.add('side-nav--animatable');
    this.sideNavEl.classList.remove('side-nav--visible');
    this.detabinator.inert = true;
    this.sideNavEl.addEventListener('transitionend', this.onTransitionEnd);
  }

  toggleSideNav () {
    this.showSideNav;
    debugger
  }
}

new SideNav();

I also have an hamburger.js file to animate my hamburger button but I don't think that cause any trouble.

Thank's for the help.

Hugo
  • 163
  • 4
  • 16

1 Answers1

1

You are missing brackets in the method invocation:

toggleSideNav () {
    this.showSideNav;
    debugger // what is that for ?
}

Should be:

toggleSideNav () {
    this.showSideNav();
    debugger // what is that for ?
}
mnille
  • 1,328
  • 4
  • 16
  • 20
  • Thank's for the answer but can you explain why it doesn't work because in my eventListener I did it and it's OK. `addEventListeners () { this.toggleMenuEl.addEventListener('click', this.toggleSideNav); ...` The `debugger` stop the code and open the dev tools in Chrome. It's a kind of `breakpoint`. – Hugo Aug 29 '16 at 09:19
  • in the eventListener you are passing to the handler an object that is a function type object. You do not need to invoke the function because the handler will invoke it for you. – Gian Luca Cecchi Sep 20 '16 at 09:36