Onclick 使用 Javascript 将图标旋转 180 度

时间:2021-05-12 18:58:58

标签: javascript

我需要选择所有三个图标,并在用户点击它们时让它们旋转 180 度。使用当前编写的代码,它只针对第一个箭头图标,允许它旋转 180 度并返回。然而,当我点击其他两个图标时,它们不会旋转/并且第一个图标会旋转,即使我没有点击第一个图标。

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>

4 个答案:

答案 0 :(得分:1)

ID 必须是唯一的。

委托点击 - 更简单

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>

答案 1 :(得分:1)

您可以为所有箭头添加事件侦听器,这样您就不需要 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>

答案 2 :(得分:1)

就像其他人写的:id 必须是唯一的。此外,您不需要它,因为您只需使用事件的目标并切换其类 .open(如果它具有类 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>

答案 3 :(得分:0)

这是因为 id 属性是唯一的,不能与多个元素一起使用。 getElementById 将返回带有 idicon 的第一个元素,产生您看到的结果。要修复,我建议将参数传递给您的函数,无论它是 event 还是只是一个数字。在这个例子中,我将使用一个数字:

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>

每个图像上的 onclick() 将触发此函数,发送一个数字参数,允许引用正确的箭头。然后,当它翻转时,代码就会知道用户引用的是什么图像。