className only changing every other class

2020-02-11 17:18发布

I'm performing a small text with JavaScript with the getElementsByClassName() and I am getting some unwanted results. I would like the script to change each CSS class to a new class. The issue is that every other class is only changing...

I would like to use pure js how this issue as it is for practice purposes.

The first thing that came to mind was white spaces, although when removing the this did not make any differnce.

Can anyone point our what I am doing wrong?

<html>
    <head>
       <link rel="stylesheet" type="text/css" href="default.css">
    </head>
    <body>
        <div class="block-default">BLOCK1</div>
        <div class="block-default">BLOCK2</div>
        <div class="block-default">BLOCK3</div>
        <div class="block-default">BLOCK4</div>
        <div class="block-default">BLOCK5</div>
        <div class="block-default">BLOCK6</div>
        <div class="block-default">BLOCK7</div>
        <div class="block-default">BLOCK8</div>
        <script>

    var blockSet = document.getElementsByClassName("block-default");
    var blockSetLength = blockSet.length;

    blockSet[0].className = "block-selected";
    blockSet[1].className = "block-selected";
    blockSet[2].className = "block-selected";
    blockSet[3].className = "block-selected";
    blockSet[4].className = "block-selected";
    blockSet[5].className = "block-selected";
    blockSet[6].className = "block-selected";
    blockSet[7].className = "block-selected";   

        </script>
    </body>
</html>

CSS Classes:

.block-default {
    width: 100px;
    height:50px;
    background-color: green;
    border: 1px solid red;
    padding:10px;
}

.block-selected {
    width: 100px;
    height:50px;
    background-color: blue;
    border: 1px solid white;
    padding:10px;
 }

15条回答
小情绪 Triste *
2楼-- · 2020-02-11 18:09

document.getElementsByClassName returns a HTMLCollection object, which is live

An HTMLCollection in the HTML DOM is live; it is automatically updated when the underlying document is changed.

So when you call

blockSet[0].className = "block-selected";

You changed the underlying document and that item is not in the collection anymore (the blockSet[0] is now the second item in your original selection).

查看更多
贼婆χ
3楼-- · 2020-02-11 18:12

function change() {
  var blockSet = document.getElementsByClassName("block-default");
  var blockSetLength = blockSet.length;

  for (var i = 0; i < blockSetLength; i++) {

    blockSet[0].className = "block-selected";
  }
}
.block-default {
  width: 100px;
  height: 50px;
  background-color: green;
  border: 1px solid red;
  padding: 10px;
}
.block-selected {
  width: 100px;
  height: 50px;
  background-color: blue;
  border: 1px solid white;
  padding: 10px;
}
<button onclick="change()">change</button>

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>

what you were doing wrong is every time you change the class the colllection re-evaluates and decreases in size.

查看更多
够拽才男人
4楼-- · 2020-02-11 18:12

Definition and Usage

  1. The getElementsByClassName() method returns a collection of all elements in the document with the specified class name, as a NodeList object.

  2. The NodeList object represents a collection of nodes. The nodes can be accessed by index numbers. The index starts at 0.

The use of this property is discouraged because of performance implications (due to the live DOMCollection where any changes to the document must be reflected on the returned object immediately) and complexity (the removal of an element from the document will result in immediate changes to the collection).

And by just adding only blockSet[0].className = "block-selected"; and by clicking on the button it colord each div by each click so we need to click 8 times in order to color all the divs and see the live example below

function myFunction() {
  var blockSet = document.getElementsByClassName('block-default');

  blockSet[0].className = "block-selected";

}
.block-default {
  width: 100px;
  height: 50px;
  background-color: green;
  border: 1px solid red;
  padding: 10px;
}
.block-selected {
  width: 100px;
  height: 50px;
  background-color: blue;
  border: 1px solid white;
  padding: 10px;
}
<button onclick="myFunction()">change</button>

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>

And by adding only var blockSet = document.getElementsByClassName('block-default'); alert("Length are: " + blockSet.length + "\nFirst Item is: " + blockSet[0].childNodes[0].nodeValue); without the rest it will alert

  • Length are: 8
  • First Item is: block1

As in the below live example:

function myFunction() {
  var blockSet = document.getElementsByClassName('block-default');

  /*
      blockSet[0].className = "block-selected";
      blockSet[1].className = "block-selected";
      blockSet[2].className = "block-selected";
      blockSet[3].className = "block-selected";
      blockSet[4].className = "block-selected";
      blockSet[5].className = "block-selected";
      blockSet[6].className = "block-selected";
      blockSet[7].className = "block-selected";*/

  alert("Length are: " + blockSet.length + "\nFirst Item is: " + blockSet[0].childNodes[0].nodeValue);
}
.block-default {

  width: 100px;

  height: 50px;

  background-color: green;

  border: 1px solid red;

  padding: 10px;

}

.block-selected {

  width: 100px;

  height: 50px;

  background-color: blue;

  border: 1px solid white;

  padding: 10px;

}
<button onclick="myFunction()">change</button>

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>

Or we can use it use document.getElementsByClassNamewith for loopso a close alternative is querySelectorAll as Rick Hitchcock answered it.

function myFunction() {
  var blockSet = document.querySelectorAll('.block-default');
  blockSet[0].className = "block-selected";
  blockSet[1].className = "block-selected";
  blockSet[2].className = "block-selected";
  blockSet[3].className = "block-selected";
  blockSet[4].className = "block-selected";
  blockSet[5].className = "block-selected";
  blockSet[6].className = "block-selected";
  blockSet[7].className = "block-selected";
}
.block-default {
  width: 100px;
  height: 50px;
  background-color: green;
  border: 1px solid red;
  padding: 10px;
}
.block-selected {
  width: 100px;
  height: 50px;
  background-color: blue;
  border: 1px solid white;
  padding: 10px;
}
<button onclick="myFunction()">change</button>

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>

I hope my post it helps, let me know if you have any question.

查看更多
登录 后发表回答