简体   繁体   中英

Onclick rotate icon 180 degrees using Javascript

I am needed to select all three icons and be able to have them rotate 180 when a user clicks on them. With the current code written, it is only targeting the first arrow icon, allowing it to turn 180 and back. Yet when I click on the other two icons, they do not rotate/ AND the first icon rotates even though I didn't click on the first icon.

 const arrowFlip = () => { let div = document.getElementById("nav__links"); let icon = document.getElementById("icon"); let open = false; div.addEventListener("click", function() { if (open) { icon.className = "menu-arrow-down"; } else { icon.className = "menu-arrow-down open"; } open =;open; }); }; arrowFlip();
 .menu-arrow-down { transform: rotate(0deg); transition: 1s linear; }.menu-arrow-down.open { transform: rotate(180deg); transition: 1s linear; }
 <ul id="nav__links" class="nav__links"> <div class="desktop__nav"> <li class="parent"> <a href="#">Product</a> <img id="icon" class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>Overview</li> <li>Pricing</li> <li>Marketplace</li> <li>Features</li> <li>Integrations</li> </ul> </li> <li class="parent"> <a href="#">Company</a> <img id="icon" class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>About</li> <li>Team</li> <li>Blog</li> <li>Careers</li> </ul> </li> <li class="parent"> <a href="#">Connect</a> <img id="icon" class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>Contact</li> <li>Newsletter</li> <li>LinkedIn</li> </ul> </li> </div>

IDs need to be unique.

Delegate the click - it is much simpler

 document.getElementById("nav__links").addEventListener("click", function(e) { const tgt = e.target; if (tgt.classList.contains('menu-arrow-down')) { // make sure we only target elements with this class tgt.classList.toggle('open'); // here you can test tgt.classList.contains('open') to see the state } });
 .menu-arrow-down { transform: rotate(0deg); transition: 1s linear; }.menu-arrow-down.open { transform: rotate(180deg); transition: 1s linear; }
 <ul id="nav__links" class="nav__links"> <div class="desktop__nav"> <li class="parent"> <a href="#">Product</a> <img class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>Overview</li> <li>Pricing</li> <li>Marketplace</li> <li>Features</li> <li>Integrations</li> </ul> </li> <li class="parent"> <a href="#">Company</a> <img class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>About</li> <li>Team</li> <li>Blog</li> <li>Careers</li> </ul> </li> <li class="parent"> <a href="#">Connect</a> <img class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>Contact</li> <li>Newsletter</li> <li>LinkedIn</li> </ul> </li> </div>

You can add event listeners to all arrows, that way you won't need an id:

 let allArrows = document.querySelectorAll(".menu-arrow"); allArrows.forEach(arrow => { arrow.addEventListener('click', function() { this.className = this.className === "menu-arrow-down open"? "menu-arrow-down": "menu-arrow-down open"; }); });
 .menu-arrow-down { transform: rotate(0deg); transition: 1s linear; }.menu-arrow-down.open { transform: rotate(180deg); transition: 1s linear; }
 <ul id="nav__links" class="nav__links"> <div class="desktop__nav"> <li class="parent"> <a href="#">Product</a> <img id="icon" class="menu-arrow menu-arrow-down" src="https://placekitten.com/50/50" alt="arrow" /> <ul class="sub-menu"> <li>Overview</li> <li>Pricing</li> <li>Marketplace</li> <li>Features</li> <li>Integrations</li> </ul> </li> <li class="parent"> <a href="#">Company</a> <img id="icon" class="menu-arrow menu-arrow-down" src="https://placekitten.com/50/50" alt="arrow" /> <ul class="sub-menu"> <li>About</li> <li>Team</li> <li>Blog</li> <li>Careers</li> </ul> </li> <li class="parent"> <a href="#">Connect</a> <img id="icon" class="menu-arrow menu-arrow-down" src="https://placekitten.com/50/50" alt="arrow" /> <ul class="sub-menu"> <li>Contact</li> <li>Newsletter</li> <li>LinkedIn</li> </ul> </li> </div>

Like the others wrote: an id has to be unique. Furthermore you don't need it since you simply can use the target of the event and toggle its class .open if it has the class menu-arrow .

 document.getElementById("nav__links").addEventListener("click", function(event) { if (event.target.className.includes('menu-arrow')) { event.target.classList.toggle('open'); } });
 .menu-arrow-down { transform: rotate(0deg); transition: 1s linear; }.menu-arrow-down.open { transform: rotate(180deg); transition: 1s linear; }
 <ul id="nav__links" class="nav__links"> <div class="desktop__nav"> <li class="parent"> <a href="#">Product</a> <img class="menu-arrow menu-arrow-down" src="https://via.placeholder.com/160x120" alt="arrow" /> <ul class="sub-menu"> <li>Overview</li> <li>Pricing</li> <li>Marketplace</li> <li>Features</li> <li>Integrations</li> </ul> </li> <li class="parent"> <a href="#">Company</a> <img class="menu-arrow menu-arrow-down" src="https://via.placeholder.com/160x120" alt="arrow" /> <ul class="sub-menu"> <li>About</li> <li>Team</li> <li>Blog</li> <li>Careers</li> </ul> </li> <li class="parent"> <a href="#">Connect</a> <img class="menu-arrow menu-arrow-down" src="https://via.placeholder.com/160x120" alt="arrow" /> <ul class="sub-menu"> <li>Contact</li> <li>Newsletter</li> <li>LinkedIn</li> </ul> </li> </div>

This is because the id attribute is unique and cannot be used with multiple elements. getElementById will return the first element with the id of icon , producing the result you are seeing. To fix, I suggest passing a parameter to your function, whether it's an event or simply a number. In this example, I'll use a number:

 let open = false; const arrowFlip = (number) => { let icon = document.getElementsByClassName("icon")[number]; if (open) { icon.className = "icon menu-arrow-down"; } else { icon.className = "icon menu-arrow-down open"; } open =;open; };
 .menu-arrow-down { transform: rotate(0deg); transition: 1s linear; }.menu-arrow-down.open { transform: rotate(180deg); transition: 1s linear; }
 <ul id="nav__links" class="nav__links"> <div class="desktop__nav"> <li class="parent"> <a href="#">Product</a> <img class="icon" onclick="arrowFlip(0)" class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>Overview</li> <li>Pricing</li> <li>Marketplace</li> <li>Features</li> <li>Integrations</li> </ul> </li> <li class="parent"> <a href="#">Company</a> <img class="icon" onclick="arrowFlip(1)"class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>About</li> <li>Team</li> <li>Blog</li> <li>Careers</li> </ul> </li> <li class="parent"> <a href="#">Connect</a> <img class="icon" onclick="arrowFlip(2)"class="menu-arrow menu-arrow-down" src="./images/icon-arrow-light.svg" alt="arrow" /> <ul class="sub-menu"> <li>Contact</li> <li>Newsletter</li> <li>LinkedIn</li> </ul> </li> </div>

The onclick() on each image will trigger this function, sending a number parameter, allowing the correct arrow to be referenced. Then, when it flips, the code will know what image the user is referencing to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM