如何使用 document.getElementsByClassName 和 Element.classList 正确切换类 [英] How to correctly toggle classes using document.getElementsByClassName and Element.classList

查看:40
本文介绍了如何使用 document.getElementsByClassName 和 Element.classList 正确切换类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个页面,我希望能够在其中打开或关闭特定元素上的类.

为了做到这一点,我编写了一个函数:

function toggleClass(obj) {警报(obj.className);Array.from(document.getElementsByClassName(obj.className)).forEach(function(element) {element.classList.toggle(obj.className);});}

由表中的项目调用,例如 <td style=""><span class="determiner" onclick="toggleClass(this)">Determiner</span></td>.

当我第一次单击该项目时,这可以正常工作,触发警报并删除该类.当我再次单击表中的同一项目以尝试切换/添加类时,警报会触发(因为类已被删除,所以为空)但未添加该类.

谁能告诉我我在这里做错了什么?

function toggleClass(obj) {警报(obj.className);Array.from(document.getElementsByClassName(obj.className)).forEach(function(element) {element.classList.toggle(obj.className);});}

.determiner {/* 颜色:RGB(248, 8, 8);*/边框:1px 实心 rgb(248, 8, 8);}.介词{颜色:RGB(40、18、236);/* 边框:1px 实心 rgb(40, 18, 236);*/}.动词存在{颜色:RGB(13、146、68);/* 边框:3px 实心 rgb(13, 146, 68);*/}span[class^='名词-'], span[class*='名词-']{颜色:#F00;}

<table class="grammar table table-hover" data-toggle="table" data-sort-name="instance_use" 数据-sort-order="desc"><thead><tr><th style="" data-field="grammar_type" tabindex="0"><div class="th-inner sortable both">语法类型</div><;div class="fht-cell"></div></th><th style="" data-field="instance_use" tabindex="0"><div class="th-内部可排序的两个 desc">使用实例</div><div class="fht-cell"></div></th></tr></thead><tbody><tr data-index="0"><td style=""><span class="adverb" onclick="toggleClass(this)">副词</span></td><td style="">2 </td></tr><tr data-index="1"><td style=""><span class="动词-present" onclick="toggleClass(this)">动词,呈现</span></td><td style="">2 </td></tr><tr 数据-index="2"><td style=""><span class="determiner" onclick="toggleClass(this)">Determiner</span></td><td style="">2 </td></tr><tr data-index="3"><td style=""><span class="noun-sing-or-mass"onclick="toggleClass(this)"> 名词,唱歌.或质量</span></td><td style="">1 </td></tr><tr data-index="4"><td style=""><span class="" onclick="toggleClass(this)">介词</span></td><td style="">1 </td></tr><;tr data-index="5"><td style=""><span class="noun-plural" onclick="toggleClass(this)">名词,复数</span></td><td style="">1 </td></tr><tr data-index="6"><td style=""><span class="comma" onclick="toggleClass(this)">逗号</span></td><td style="">1 </td></tr><tr data-index="7"><td style=""><span class="personal-pronoun" onclick="toggleClass(this)">人称代词</span></td><td style="">1 </td></tr></tbody><div id="story_text"><span style="white-space: pre-line"><span class="adverb">这里</span><span class="verb-present">is</span><span class="determiner">a</span><span class="noun-sing-or-mass">story</span><span class="">with</span><span class="determiner">no</span><span class="名词复数">逗号</span><span class="逗号">,</span><span class="副词">现在</span><span class="personal-pronoun">it</span><span class="verb-present">确实</span></span>

解决方案

问题是你一直在引用 obj.className,但是在 forEach 循环中,一旦被点击的元素被迭代,obj.className 变成空白,所以进一步迭代(比如中的a"是一个故事),传递给element.classList.toggle 为空.

另一个问题是,当您再次尝试单击该元素时,它没有现有的类,因此 obj.className 为空 - 没有可切换回的类.

不要在 HTML 属性中添加处理程序(这与 eval 一样糟糕),尝试遍历所有需要处理程序的元素事先,这样您就可以构建一个数组您希望能够切换的每个 className 的元素.

一个不太优雅的解决方案(需要更少的更改)是切换一个 不同的 类来覆盖 colorborder 属性determiner 和其他类的:

function toggleClass(obj) {const className = obj.classList[0];document.querySelectorAll('.' + className).forEach(element => {element.classList.toggle('空白');});}

.determiner {/* 颜色:RGB(248, 8, 8);*/边框:1px 实心 rgb(248, 8, 8);}.介词{颜色:RGB(40、18、236);/* 边框:1px 实心 rgb(40, 18, 236);*/}.动词存在{颜色:RGB(13、146、68);/* 边框:3px 实心 rgb(13, 146, 68);*/}跨度[class^='名词-'],span[class*='名词-'] {颜色:#F00;}.空白的 {边框:0;颜色:黑色!重要;}

<table class="grammar table table-hover" data-toggle="table" data-sort-name="instance_use" 数据-sort-order="desc"><thead><tr><th style="" data-field="grammar_type" tabindex="0"><div class="th-inner sortable both">语法类型</div><;div class="fht-cell"></div></th><th style="" data-field="instance_use" tabindex="0"><div class="th-内部可排序的两个 desc">使用实例</div><div class="fht-cell"></div></th></tr></thead><tbody><tr data-index="0"><td style=""><span class="adverb" onclick="toggleClass(this)">副词</span></td><td style="">2 </td></tr><tr data-index="1"><td style=""><span class="动词-present" onclick="toggleClass(this)">动词,呈现</span></td><td style="">2 </td></tr><tr 数据-index="2"><td style=""><span class="determiner" onclick="toggleClass(this)">Determiner</span></td><td style="">2 </td></tr><tr data-index="3"><td style=""><span class="noun-sing-or-mass"onclick="toggleClass(this)"> 名词,唱歌.或质量</span></td><td style="">1 </td></tr><tr data-index="4"><td style=""><span class="" onclick="toggleClass(this)">介词</span></td><td style="">1 </td></tr><;tr data-index="5"><td style=""><span class="noun-plural" onclick="toggleClass(this)">名词,复数</span></td><td style="">1 </td></tr><tr data-index="6"><td style=""><span class="comma" onclick="toggleClass(this)">逗号</span></td><td style="">1 </td></tr><tr data-index="7"><td style=""><span class="personal-pronoun" onclick="toggleClass(this)">人称代词</span></td><td style="">1 </td></tr></tbody><div id="story_text"><span style="white-space: pre-line"><span class="adverb">这里</span><span class="verb-present">is</span><span class="determiner">a</span><span class="noun-sing-or-mass">story</span><span class="">with</span><span class="determiner">no</span><span class="名词复数">逗号</span><span class="逗号">,</span><span class="副词">现在</span><span class="personal-pronoun">it</span><span class="verb-present">确实</span></span>

I have a page where I want to be able to toggle classes on particular elements on or off.

In an attempt to do this I have written a function:

function toggleClass(obj) {
    alert(obj.className);
      Array.from(document.getElementsByClassName(obj.className)).forEach(function(element) {
        element.classList.toggle(obj.className);
    });
}

which is called by items in a table e.g <td style=""><span class="determiner" onclick="toggleClass(this)">Determiner</span></td>.

This works fine when I first click the item, the alert is triggered and the class is removed. When I click the same item in the table again to try and toggle/add the class the alert fires (empty because the class has been removed) but the class is not added.

Can anyone advise what I am doing wrong here?

function toggleClass(obj) {
    alert(obj.className);
      Array.from(document.getElementsByClassName(obj.className)).forEach(function(element) {
        element.classList.toggle(obj.className);
    });
}

.determiner {
  /* color: rgb(248, 8, 8); */
  border: 1px solid rgb(248, 8, 8);
}

.preposition {
  color: rgb(40, 18, 236);
  /* border: 1px solid rgb(40, 18, 236); */
}

.verb-present {
  color: rgb(13, 146, 68);
  /* border: 3px solid rgb(13, 146, 68); */
}

span[class^='noun-'], span[class*=' noun-']{
  color: #F00;
}

<table class="grammar table table-hover" data-toggle="table" data-sort-name="instance_use" data-sort-order="desc">
            <thead><tr><th style="" data-field="grammar_type" tabindex="0"><div class="th-inner sortable both">Grammar Type</div><div class="fht-cell"></div></th><th style="" data-field="instance_use" tabindex="0"><div class="th-inner sortable both desc">Instances of Use</div><div class="fht-cell"></div></th></tr></thead>
            <tbody><tr data-index="0"><td style=""><span class="adverb" onclick="toggleClass(this)">Adverb</span></td><td style="">2 </td></tr><tr data-index="1"><td style=""><span class="verb-present" onclick="toggleClass(this)">Verb, present</span></td><td style="">2 </td></tr><tr data-index="2"><td style=""><span class="determiner" onclick="toggleClass(this)">Determiner</span></td><td style="">2 </td></tr><tr data-index="3"><td style=""><span class="noun-sing-or-mass" onclick="toggleClass(this)">Noun, sing. or mass</span></td><td style="">1 </td></tr><tr data-index="4"><td style=""><span class="" onclick="toggleClass(this)">Preposition</span></td><td style="">1 </td></tr><tr data-index="5"><td style=""><span class="noun-plural" onclick="toggleClass(this)">Noun, plural</span></td><td style="">1 </td></tr><tr data-index="6"><td style=""><span class="comma" onclick="toggleClass(this)">Comma</span></td><td style="">1 </td></tr><tr data-index="7"><td style=""><span class="personal-pronoun" onclick="toggleClass(this)">Personal pronoun</span></td><td style="">1 </td></tr></tbody>
        </table>
        
<div id="story_text">
            <span style="white-space: pre-line">
            <span class="adverb">here</span> <span class="verb-present">is</span> <span class="determiner">a</span> <span class="noun-sing-or-mass">story</span> <span class="">with</span> <span class="determiner">no</span> <span class="noun-plural">commas</span><span class="comma">,</span> <span class="adverb">now</span> <span class="personal-pronoun">it</span> <span class="verb-present">does</span>
            </span>
        </div>

解决方案

The problem is that you keep referencing obj.className, but in the forEach loop, once the clicked element is iterated over, the obj.className becomes blank, so on further iterations (such as the "a" in is a story), the string passed to element.classList.toggle is blank.

Another problem is that when you try to click the element again, it has no existing class, so obj.className is empty - there's no class to toggle back on.

Instead of adding handlers in HTML attributes (which is as bad as eval), try iterating through all elements that need a handler beforehand, so you can build an array of elements for each className you want to be able to toggle.

A less elegant solution (that would require many fewer changes) would be to toggle a different class which overrides the color and border properties of the determiner and other classes:

function toggleClass(obj) {
  const className = obj.classList[0];
  document.querySelectorAll('.' + className).forEach(element => {
    element.classList.toggle('blank');
  });
}

.determiner {
  /* color: rgb(248, 8, 8); */
  border: 1px solid rgb(248, 8, 8);
}

.preposition {
  color: rgb(40, 18, 236);
  /* border: 1px solid rgb(40, 18, 236); */
}

.verb-present {
  color: rgb(13, 146, 68);
  /* border: 3px solid rgb(13, 146, 68); */
}

span[class^='noun-'],
span[class*=' noun-'] {
  color: #F00;
}

.blank {
  border: 0;
  color: black !important;
}

<table class="grammar table table-hover" data-toggle="table" data-sort-name="instance_use" data-sort-order="desc">
            <thead><tr><th style="" data-field="grammar_type" tabindex="0"><div class="th-inner sortable both">Grammar Type</div><div class="fht-cell"></div></th><th style="" data-field="instance_use" tabindex="0"><div class="th-inner sortable both desc">Instances of Use</div><div class="fht-cell"></div></th></tr></thead>
            <tbody><tr data-index="0"><td style=""><span class="adverb" onclick="toggleClass(this)">Adverb</span></td><td style="">2 </td></tr><tr data-index="1"><td style=""><span class="verb-present" onclick="toggleClass(this)">Verb, present</span></td><td style="">2 </td></tr><tr data-index="2"><td style=""><span class="determiner" onclick="toggleClass(this)">Determiner</span></td><td style="">2 </td></tr><tr data-index="3"><td style=""><span class="noun-sing-or-mass" onclick="toggleClass(this)">Noun, sing. or mass</span></td><td style="">1 </td></tr><tr data-index="4"><td style=""><span class="" onclick="toggleClass(this)">Preposition</span></td><td style="">1 </td></tr><tr data-index="5"><td style=""><span class="noun-plural" onclick="toggleClass(this)">Noun, plural</span></td><td style="">1 </td></tr><tr data-index="6"><td style=""><span class="comma" onclick="toggleClass(this)">Comma</span></td><td style="">1 </td></tr><tr data-index="7"><td style=""><span class="personal-pronoun" onclick="toggleClass(this)">Personal pronoun</span></td><td style="">1 </td></tr></tbody>
        </table>
        
<div id="story_text">
            <span style="white-space: pre-line">
            <span class="adverb">here</span> <span class="verb-present">is</span> <span class="determiner">a</span> <span class="noun-sing-or-mass">story</span> <span class="">with</span> <span class="determiner">no</span> <span class="noun-plural">commas</span><span class="comma">,</span> <span class="adverb">now</span> <span class="personal-pronoun">it</span> <span class="verb-present">does</span>
            </span>
        </div>

这篇关于如何使用 document.getElementsByClassName 和 Element.classList 正确切换类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆