getElementsByClassName不起作用,但getElementById可以?

7

我写了一个脚本,它的目标是停止显示图像一和二,同时允许图像三保持显示并移动到它们的位置。当我使用div Id而不是div类时,它可以正常工作,但我更喜欢使用div类来将元素分组,如下所示:

 function myFunction() {
     var y = document.getElementsByClassName("firstimage secondimage");
     if (y.style.display === 'none') {
           y.style.display = 'block';
     } else {
           y.style.display = 'none';
     }
 }

相比于这种方式(如果我选择包含更多元素来节省空间):

 function myFunction() {
     var x = document.getElementById("firstimage");
     if (x.style.display === 'none') {
          x.style.display = 'block';
     } else {
          x.style.display = 'none';
     }

     var y = document.getElementById("secondimage");
     if (y.style.display === 'none') {
          y.style.display = 'block';
     } else {
          y.style.display = 'none';
     }
}

我认为仅仅将div id更改为div class,将#imagenumber更改为.imagenumber(除了我上面描述的javascript更改之外)就可以解决问题,但是当我这样做时,脚本停止工作。 我需要脚本以与我在下面粘贴的代码相同的方式运行,但使用div类而不是div Id。 请告诉我我错在哪里。
CSS:
#firstimage {
    width: 100px;
    height: 100px;
    padding: 0px 0;
    text-align: center;
    background-color: green;
    margin-top:20px;
    color: white;
}

#secondimage {
    width: 100px;
    height: 100px;
    padding: 0px 0;
    text-align: center;
    background-color: blue;
    margin-top:20px;
    color: white;
}

#thirdimage {
    width: 100px;
    height: 100px;
    padding: 0px 0;
    text-align: center;
    background-color: red;
    margin-top:20px;
    color: white;
}

HTML:

<button onclick="myFunction()">Try me</button>

<div id="firstimage">
    DIV element.
</div>

<div id="secondimage">
    A second DIV element.
</div>

<div id="thirdimage">
    A third DIV element.
</div>

Javascript:

function myFunction() {
     var x = document.getElementById("firstimage");
     if (x.style.display === 'none') {
          x.style.display = 'block';
     } else {
          x.style.display = 'none';
     }

     var y = document.getElementById("secondimage");
     if (y.style.display === 'none') {
          y.style.display = 'block';
     } else {
          y.style.display = 'none';
     }
}

这并不难。你启动调试器,在调用 getElementsByClassName 后的那一行上设置断点,然后检查变量 y。接着尝试检查 y.style。你应该能够很快地弄清楚发生了什么。或者,你可以在 Stack Overflow 上搜索“getElementsByClassName 不起作用”,因为这里有许多关于这个主题的问题,从六年前开始。 - user663031
2个回答

10

document.getElementsByClassName 返回一个元素数组,因此您需要遍历该数组并在循环中对每个元素进行操作。

`document.getElementsByClassName` 返回的是一个包含多个元素的数组,所以您需要使用循环来逐一处理这些元素。

5
它返回一个“类数组对象,其中包含所有子元素”,这与元素数组不同。 - brk
1
@user2181397 - 是的。它返回一个HTMLCollection。如果您将以下行添加到您的JS中,您仍然可以在它们上使用数组的forEach方法,这使它们更加易于使用。HTMLCollection.prototype.forEach = Array.prototype.forEach; - enhzflep
2
@enhzflep 修改本地对象的原型是一个可怕的想法。为什么不直接使用 [].slice.call(document.getElementsByClassName('foobar')).forEach()?更好的方法是使用document.querySelector(),它会实际执行OP想要的操作。 - user4639281
@TinyGiant - 因为我还没有遇到有人向我赞扬更冗长的方法胜过我所建议的方法。在看到您的评论后快速阅读后,发现问题可能出在未来可能会出现的故障上。这似乎与将自定义属性添加到 HTML 元素中并最终成为标准化的情况没有多少不同。autosuggestlang都会让人想到(也许是错误的)。这就是为什么它被认为是一个可怕的想法? - enhzflep
1
@enhzflep 从扩展本地原型可能会出现许多问题。这已经被反复讨论过无数次了。有很多信息可以获取。如果您拒绝承认这些信息并坚持破坏事物,那是您的权利。如果页面上除了您的代码之外还有其他代码,并且该代码期望本地对象以某种方式存在,则您的代码将干扰其正常运行。 - user4639281
显示剩余2条评论

4
你应该使用getElementsByClassName()querySelectorAll()来收集所有的div.Klass(Klass是任意名称)。下面的代码片段使用了querySelectorAll(),详细信息在源代码中有注释。

function toggleDiv() {
  // Collect all .image into a NodeList
  var xs = document.querySelectorAll(".image");
  // Declare i and qty for "for" loop
  var i, qty = xs.length;
  // Use "for" loop to iterate through NodeList
  for (i = 0; i < qty; i++) {
    // If this div.image at index [i] is "none"...
    if (xs[i].style.display === 'none') {
      // then make it "block"... 
      xs[i].style.display = 'block';
    } else {
      // otherwise set display to "none"
      xs[i].style.display = 'none';
    }
  }
}
#firstimage {
  width: 100px;
  height: 100px;
  padding: 0px 0;
  text-align: center;
  background-color: green;
  margin-top: 20px;
  color: white;
}
#secondimage {
  width: 100px;
  height: 100px;
  padding: 0px 0;
  text-align: center;
  background-color: blue;
  margin-top: 20px;
  color: white;
}
#thirdimage {
  width: 100px;
  height: 100px;
  padding: 0px 0;
  text-align: center;
  background-color: red;
  margin-top: 20px;
  color: white;
}
<button onclick="toggleDiv()">Try me</button>

<div id="firstimage" class='image'>
  DIV element.
</div>

<div id="secondimage" class='image'>
  A second DIV element.
</div>

<div id="thirdimage" class='img'>
  A third DIV element.
</div>

在这个函数中,只需要使用类似于示例中展示的NodeList之类的“类数组”对象。如果要对div进行更高级的处理,比如在每个div上运行一个函数并返回结果,那么需要将“类数组”对象转换为数组才能运行map、forEach、slice等方法。

这很有帮助。然而,我的代码的目标是停止显示图像一和二,同时允许图像三保持显示并移动到它们的位置。 - Jack Elwell
我不记得问题中有提到这一点,但我会更新我的答案以符合要求... - zer00ne
你说得对,我会回去加上的,感谢你的指出和帮助! - Jack Elwell
@JackElwell 好的,完成了。 - zer00ne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接