R
R
Roman Rodionov2015-11-26 22:43:02
css
Roman Rodionov, 2015-11-26 22:43:02

Animation problem: only plays once. How best to implement?

Hello, friends!
I recently finished studying the Head First book "Learning JavaScript Programming".
For practice, I develop a website using pure JS.
When you press the sandwich button, the animation starts (the button and the logo shrink and move, and the menu pops up from above).
The problem is that when you click the second and subsequent times, the animation should play in reverse, but everything returns to its place without animation.
Please, tell me what is the problem here, as well as a more convenient way to implement this in pure JS and CSS.
Implemented like this:

<div id="sandwich" onclick="animateSandwichMenu()">
        <div id="upper-line"></div>
        <div id="middle-left-line"></div>
        <div id="middle-right-line"></div>
        <div id="bottom-line"></div>
      </div>

      <!--******************  Navigation menu  *****************-->
      <nav id="nav" class="nav">
        <ul>
          <li><a href="#">ABOUT</a></li>
          <span>\\</span>
          <li><a href="#">TEAM</a></li>
          <span>\\</span>
          <li><a href="#">SERVICES</a></li>
          <span>\\</span>
          <li><a href="#">WORKS</a></li>
          <span>\\</span>
          <li><a href="#">BLOG</a></li>
          <span>\\</span>
          <li><a href="#">CONTACT</a></li>
        </ul>
      </nav>

/************************SANDWICH MENU ANIMATION*************************/
var menuOn = false;
function animateSandwichMenu() {
  var lines = document.getElementById('sandwich').childNodes;
  /*Get style attribute value*/
  function getStyleValue(animationClassName) {
    /*Set animation-direction*/
    function getAnimDirection() {
      if (!menuOn) {return 'normal';}
      else {return 'reverse';}
    }
    /*Return value*/
    return 'animation-name: ' + animationClassName + '; ' +
         	 'animation-fill-mode: both; ' +
           'animation-duration: 1s; ' +
           'animation-direction: ' + getAnimDirection() + ';';
  }
  /*Sandwich lines animation*/
  for (var i = 0; i < lines.length; i++) {
    if (lines[i] instanceof(HTMLDivElement)) {
      var animationClassName = lines[i].id + "-animation";
      lines[i].setAttribute('style', getStyleValue(animationClassName))
    }
  }
  /*Other animation*/
  var elementsId = ['sandwich',
                    'logo',
                    'menu-for-mobile',
                    'nav'];
  for (var i = 0; i < elementsId.length; i++ ) {
    addStyle(elementsId[i], elementsId[i] + '-animation');
  }

  function addStyle(elementId, animationClassName) {
    var elem = document.getElementById(elementId);
    elem.removeAttribute('style');
    console.log(elem);
    elem.setAttribute('style', getStyleValue(animationClassName));
  }
  /*Toggle*/
  menuOn = !menuOn;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Roman Rodionov, 2015-11-28
@Romashishka

Tried and done!
It turns out that the animation does not complete its action, but simply stops. Therefore, it does not play on the second click in the opposite direction.
One way to stop it:
1) Clone the element on which the event is hung, after removing the style attribute from it.
2) Remove this element itself.
3) Insert its clone instead.
Here is the solution for my code:

function addStyle(elementId, animationClassName) {
...
    var elem = document.getElementById(elementId);
    var father = elem.parentNode;
    elem.removeAttribute('style');
    var newElem = elem.cloneNode(true);

    elem.parentNode.removeChild(elem);
    father.appendChild(newElem);
    newElem.setAttribute('style', getStyleValue(animationClassName));
  }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question