1

I have the following code that aims to rotate a hamburger icon by 90 deg when it is clicked, but it doesn't work why?

var menu = document.getElementById("menu");
let rotate = function() {
  document.getElementById("menu").style.transform = "rotate(90deg)";
};
menu.addEventListener("click", rotate);
#menu {
  text-decoration: none;
  color: white;
  font-size: 5vw;
  color: #66fcf1;
  cursor: default;
  position: fixed;
  margin-left: 2.5%;
}
<a href="#" id="menu">&#9776;</a>

Also on Codepen: https://codepen.io/greatscams/pen/ZEQrYog

Note: It only works once.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Greatguy
  • 91
  • 1
  • 2
  • 6
  • Please update your question with a [mcve] demonstrating the problem (the HTML is part of "minimum" here), ideally a **runnable** one using Stack Snippets (the `[<>]` toolbar button; [here's how to do one](https://meta.stackoverflow.com/questions/358992/)). – T.J. Crowder Jul 04 '20 at 09:49
  • 1
    The demo you've provided is working. – Ramesh Reddy Jul 04 '20 at 09:50
  • 1
    @RameshReddy, yeah, but only once – Greatguy Jul 04 '20 at 09:51
  • @Greatguy What should happen in the subsequent clicks should it rotate 180, 270...so on? – Ramesh Reddy Jul 04 '20 at 09:53
  • The rotation doesn't revert to normal. It works, but probably not how you expect it. Do you want it to rotate 90 degrees each time you click? – mmfallacy Jul 04 '20 at 09:54
  • @RameshReddy, well after clicked once, it should rotate by another 90deg and thus come back to its original position, since its a symmetric icon – Greatguy Jul 04 '20 at 09:54
  • Does this answer your question? [Html & JS rotate image 90 degrees on click](https://stackoverflow.com/questions/57540411/html-js-rotate-image-90-degrees-on-click) – Ivar Jul 04 '20 at 09:56
  • You can just menu.classList.toggle("rotate"); + css .rotate {...} Less code. – VXp Jul 04 '20 at 10:06

4 Answers4

2

You need to check if the element is already rotated or not. It does not happen like just rotating the paper. rotate(90deg) means you are assigning the property and not actually rotating the element.

var rotated = false;
let rotate = function () {
 if(rotated) {
   document.getElementById("menu").style.transform = "rotate(0deg)";
   rotated = false;
 } else {
   document.getElementById("menu").style.transform = "rotate(90deg)";
   rotated = true;
 }
};
1

It's only rotating once as it's being rotated by 90deg, not an additional 90deg each time.

To keep rotating each time the function runs you need something along the lines of this:

let deg = 0
let rotate = function () {
  deg = deg + 90;
  document.getElementById("menu").style.transform = `rotate(${deg}deg)`
};

So the first invocation will be rotate(90deg) the next rotate(180deg) etc

Ross Mackay
  • 940
  • 4
  • 10
0

The demo works only once because you're applying the same transform function over and over again.

The first state of the element is transform: none. When first clicking on it, you're switching it to transform: rotate(90deg).

The transform works relatively to the initial state, not the current one (it's actually stateless), so the code above will not rotate it again and again.

What you can do, depending on what you want, is:

  • remember the state and toggle the animation (from rotate(0) to rotate(90deg) and back)

or

  • count the number of rotations and then multiply 90deg by that number on every click.
Cristian Sarghe
  • 782
  • 6
  • 15
0

It only works once because the second time, you're just telling it to transform the way it's already transformed (rotated 90deg). To rotate it further, you have to tell it to rotate further. It's not additive.

For instance, extracting the angle with a regex and adding 90 to it each time, with wrap-around at 360:

let rotate = function() {
    const menuStyle = document.getElementById("menu").style;
    const current = /rotate\((\d+)deg\)/.exec(menuStyle.transform);
    let angle = current ? +current[1] : 0;
    angle = angle + 90 % 360;
    menuStyle.transform = `rotate(${angle}deg)`;
};
menu.addEventListener("click", rotate);
#menu {
  text-decoration: none;
  color: white;
  font-size: 5vw;
  color: #66fcf1;
  cursor: default;
  position: fixed;
  margin-left: 2.5%;
}
<a href="#" id="menu">&#9776;</a>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875