首页 > 解决方案 > 悬停按钮时更改多个样式属性

问题描述

我正在尝试编写一个 JS 函数来在将鼠标悬停在父标记 ( <a>) 上时更改多个元素 (包括 SVG) 的颜色。我尝试只使用 CSS,结果不是很好。

const changeColor = () => {
 document.getElementsByClassName("link-label").style.color = '#3a4646';
  document.getElementById("Arrow").style.fill = '#3a4646';
  
  document.getElementByClassName("cls-1").style.stroke ='#3a4646';
  
  document.getElementByClassName("icon-arrow").style.border = "none";
}
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200&display=swap');

.container {
  height: 200px;
  display: grid;
  place-content: center;
  font-family: 'Poppins', sans-serif;
  background-color: #3a4646;
}

.btn--rounded {
  font-size: 20px;
    color: white;
    line-height: 1;
    letter-spacing: 0.4px;
    position: relative;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    padding: 12px 15px 12px 5px;
    transition: color 0.25s linear;
    text-decoration: none;
    background: transparent;
    border: none;
    z-index: 1;
}

.btn--rounded:before {
      width: 40px;
      height: 40px;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      z-index:-1;
      animation-name: circleOut;
      animation-duration: 0.5s;
      animation-direction: alternate;
      animation-fill-mode: forwards;
}


.btn--rounded:hover:before {
          content: '';
          border: none;
          position: absolute;
          top: 50%;
          z-index: -1;
          animation-name: circleIn;
          animation-duration: 0.8s;
          animation-direction: alternate;
          animation-fill-mode: forwards;
}

.icon-arrow {
  border: 1px solid white;
  border-radius: 100%;
}


.link-label {
  padding-left: 20px;
}


@keyframes circleOut {
    0% {
      width: 100%;
      border-radius: 40px;
      background-color: #ffff;
    }
    90% {
      border-radius: 40px;
    }
    100% {
      width: 40px;
      border-radius: 100%;
      background-color: transparent;
    }
  }

@keyframes circleIn {
    0% {
      width: 60px;
      border-radius: 100%;
      background-color: transparent;
    }
    10% {
      border-radius: 60px;
    }
    100% {
      width: 100%;
      border-radius: 60px;
      background-color: #ffff;
    }
  }
<div class="container">
 
  <a href=# class="btn--rounded" onmouseover= "changeColor()">
      <div class="icon-arrow">
        <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36"><defs><style>.cls-1,.cls-2{fill:none}.cls-1{stroke:#fff}</style></defs><g id="Group_4802" transform="translate(-1113 -542)"><g id="Rectangle_2080" class="cls-1" transform="translate(1113 542)"></g><g id="Icon_Arrow_Base" transform="translate(1123 552)"><path id="Ligne" d="M15 0H0" class="cls-1" transform="translate(0 8)"/><path id="Arrow" fill="#fff" d="M12 0l-.727.727 2.753 2.753v1.039l-2.753 2.754L12 8l4-4z" transform="translate(0 4)"/></g></g></svg>
      </div>
      <div class="link-label">
      Subscribe!
      </div>
  </a>
<div>

但是,现在我不知道为什么我的函数不起作用......控制台中的所有元素都未定义。有人知道如何解决吗?

标签: javascripthtmlcsssvg

解决方案


为什么您的代码不起作用:

使用 时getElementsByClassName(),您返回一个 HTML 元素的集合,将其视为具有给定名称的类的所有元素的 HTML 列表,一个值数组是 classees 元素。即使您在该列表中可能只有一个类,Javascript 仍在寻找进一步的参考(索引标识符)来判断该列表中的哪个元素被引用。

该列表中的每个元素都必须使用索引值来标识。document.getElementsByClassName("link-label")[0],本例中的零是该 HTMLCollection 列表中的索引标识符和第一次迭代。这将是使用具有该类名称的元素的 HTMLCollection 中的索引来获取第一个孩子的静态方法。

您还可以使用选择器 -> document.querySelector(".class_name")-> 返回文档中与指定选择器匹配的第一个元素。使用 querySelector() 时,不需要使用索引标识符。

请注意,您有多个带有 的类.cls-1,您必须为这些元素创建一个循环来处理每个元素。

您还需要一个onmouseout将这些颜色和边框更改回之前的事件。动画@keyframes 将需要调整以获得 onmouseback 事件的转换。

请参阅下面的代码段:

const changeColor = () => {
  document.querySelector(".link-label").style.color = '#3a4646';
  document.getElementById("Arrow").style.fill = '#3a4646';

  // because cls1 has more that one element within is HTML Collection
  // we must loop over the collection and style each element using
  // a index identifier within a loop using a basic for loop and iterator

  let cls1 = document.querySelectorAll(".cls-1");
  for (let i = 0; i < cls1.length; i++) {
    cls1[i].style.stroke = '#3a4646';
  }
  document.querySelector(".icon-arrow").style.border = "none";
}



const changeBack = () => {
  document.querySelector(".link-label").style.color = '#eee';
  document.getElementById("Arrow").style.fill = '#eee';

  // because cls1 has more that one element within is HTML Collection
  // we must loop over the collection and style each element using
  // a index identifier within a loop using a basic for loop and iterator

  let cls1 = document.querySelectorAll(".cls-1");
  for (let i = 0; i < cls1.length; i++) {
    cls1[i].style.stroke = '#eee';
  }
  document.querySelector(".icon-arrow").style.border = "1px solid white";
}
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200&display=swap');
.container {
  height: 200px;
  display: grid;
  place-content: center;
  font-family: 'Poppins', sans-serif;
  background-color: #3a4646;
}

.btn--rounded {
  font-size: 20px;
  color: white;
  line-height: 1;
  letter-spacing: 0.4px;
  position: relative;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  padding: 12px 15px 12px 5px;
  transition: color 0.25s linear;
  text-decoration: none;
  background: transparent;
  border: none;
  z-index: 1;
}

.btn--rounded:before {
  width: 40px;
  height: 40px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: -1;
  animation-name: circleOut;
  animation-duration: 0.5s;
  animation-direction: alternate;
  animation-fill-mode: forwards;
  color: #eee;
}

.btn--rounded:hover:before {
  content: '';
  border: none;
  position: absolute;
  top: 50%;
  z-index: -1;
  animation-name: circleIn;
  animation-duration: 0.8s;
  animation-direction: alternate;
  animation-fill-mode: forwards;
}

.icon-arrow {
  border: 1px solid white;
  border-radius: 100%;
}

.link-label {
  padding-left: 20px;
}

@keyframes circleOut {
  0% {
    width: 100%;
    border-radius: 40px;
    background-color: #ffff;
  }
  90% {
    border-radius: 40px;
  }
  100% {
    width: 40px;
    border-radius: 100%;
    background-color: transparent;
  }
}

@keyframes circleIn {
  0% {
    width: 60px;
    border-radius: 100%;
    background-color: transparent;
  }
  10% {
    border-radius: 60px;
  }
  100% {
    width: 100%;
    border-radius: 60px;
    background-color: #ffff;
  }
}
<div class="container">

  <a href=# class="btn--rounded" onmouseover="changeColor()" onmouseout="changeBack()">
    <div class="icon-arrow">
      <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36">
        <defs>
          <style>.cls-1,.cls-2{fill:none}.cls-1{stroke:#fff}</style>
        </defs>
        <g id="Group_4802" transform="translate(-1113 -542)">
        <g id="Rectangle_2080" class="cls-1" transform="translate(1113 542)"></g>
        <g id="Icon_Arrow_Base" transform="translate(1123 552)">
        <path id="Ligne" d="M15 0H0" class="cls-1" transform="translate(0 8)"/>
        <path id="Arrow" fill="#fff" d="M12 0l-.727.727 2.753 2.753v1.039l-2.753 2.754L12 8l4-4z" transform="translate(0 4)"/>
        </g>
        </g>
        </svg>
    </div>
    <div class="link-label">
      Subscribe!
    </div>
  </a>
  <div>


推荐阅读