JavaScript 切换不处理具有相同 class 属性的许多元素

JavaScript Toggle not working with many elements with the same class attribute

我正在尝试将 'disable' 切换为 'active' CSS class 以使某些 SVG 的填充 属性 在单击时发生变化。

我能够正确更改第一个元素,但是当尝试对第二个和第三个 SVG 进行相同更改时,它会更改第一个 div 中第一个元素的颜色。

HTML

   <div>
       <svg onclick="toggleColor()" class="home__like disable heart">
           <use xlink:href="img/sprite.svg#icon-heart-full"></use>
       </svg>
   </div>
   <div>
       <svg onclick="toggleColor()" class="home__like disable heart">
           <use xlink:href="img/sprite.svg#icon-heart-full"></use>
       </svg>
   </div>
   <div>
       <svg onclick="toggleColor()" class="home__like disable heart">
           <use xlink:href="img/sprite.svg#icon-heart-full"></use>
       </svg>
   </div>

CSS

.disable {
    fill: #fff;
}

.active {
    fill: $color-primary;
}

JavaScript

function toggleColor() {

    const toggleHeart = document.querySelector('.heart');

    if(toggleHeart.classList.contains('disable')) {
        toggleHeart.classList.remove('disable');
        toggleHeart.classList.add('active');
    } else {
        toggleHeart.classList.remove('active');
        toggleHeart.classList.add('disable');
    }
}

您正在使用 .querySelector(),returns 文档中与提供的选择器匹配的第一个元素。

要获取多个元素,您需要使用 .querySelectorAll() which will return a static NodeList 个与选择器匹配的元素。那时你需要遍历 NodeList 并操作 类.

但是,由于您试图以 event-invoking 元素为目标,我认为您可以通过引用该元素来简化它。

function toggleColor(el, e) {
    el.classList.toggle('disable');
    el.classList.toggle('active');
}

并将您的 onclick 处理程序更改为 onclick="toggleColor(this,event);"

这是一个简短的片段:

function toggleColor(el, e) {
    el.classList.toggle('disable');
    el.classList.toggle('active');
}
.disable { color: #ccc }
.active  { color: #0095ee; }
<div>
    <svg class="disable" onclick="toggleColor(this,event);" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="currentColor" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
 </div>
 <div>
     <svg class="disable" onclick="toggleColor(this,event);" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="currentColor" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
 </div>
 <div>
     <svg class="disable" onclick="toggleColor(this,event);" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="currentColor" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
 </div>

为什么会这样?

由于heart的class元素有多个,所以不知道在哪个元素上执行脚本!这就像一位老师试图给 Bob 打电话,当 class 包含 5 个叫 Bob 的人时。

我们该如何解决这个问题?

您可以通过在脚本中提供元素的引用来更改 onclick 中的函数,例如:onclick="myFunction(this)"。现在在 javascript 中,您可以对元素做任何您想做的事情。

试试吧! 运行下面的例子!

function toggleColor(element) {

    toggleHeart = element;

    if(toggleHeart.classList.contains('disable')) {
        toggleHeart.classList.remove('disable');
        toggleHeart.classList.add('active');
    } else {
        toggleHeart.classList.remove('active');
        toggleHeart.classList.add('disable');
    }
}
.disable {
    color: blue;
}

.active {
    color: red;
}
<!--                      vvv  below we used the "this" keyword which references to the svg element -->
<div onclick="toggleColor(this)" class="disable">
    Click Me!
</div>
<div onclick="toggleColor(this)" class="disable">
    Click Me!
</div>
<div onclick="toggleColor(this)" class="disable">
    Click Me!
</div>
<div onclick="toggleColor(this)" class="disable">
    Click Me!
</div>