JS中如何将HTML集合复制到数组中而不互相改变

How to copy a HTML collection to an array in JS without changing each other

我想将网页中所有按钮的颜色保存在数组中并更改按钮的颜色。稍后我希望能够访问该颜色并再次将其返回。这是我的 HTML 代码

var all_buttons = document.getElementsByTagName('button');
var copyAllButtons = [];

for (let i = 0; i < all_buttons.length; i++) {
  copyAllButtons.push(all_buttons[i]);
}

function buttonColorChange(buttonThis) {

  if (buttonThis.value === 'red') {
    buttonsRed();
  } else if (buttonThis.value === 'reset') {
    buttonColorReset();
  }
}

function buttonsRed() {
  for (let i = 0; i < all_buttons.length; i++) {
    all_buttons[i].classList.remove(all_buttons[i].classList[1]);
    all_buttons[i].classList.add('btn-danger');
  }
}

function buttonColorReset() {
  for (let i = 0; i < all_buttons.length; i++) {
    console.log(typeof(all_buttons));
    all_buttons[i].classList.remove(all_buttons[i].classList[1]);
    console.log(copyAllButtons[0].classList);
    all_buttons[i].classList.add(copyAllButtons[i]);
  }
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

<div class="flex-box-pick-color">
  <form action="">
    <select name="backdrop" id="background" onchange="buttonColorChange(this)">
      <option value="random">Random</option>
      <option value="red">Red</option>
      <option value="reset">Reset</option>
    </select>
  </form>
  <button class="btn btn-primary">Whatever</button>
  <button class="btn btn-danger">Nothing</button>
  <button class="btn btn-warning">:)</button>
  <button class="btn btn-success">(:</button>
</div>

所以我有这个下拉菜单,如果你 select 红色,页面上的所有按钮都会变成红色。但是如果你 select 重置,它必须改变颜色。目前,copyAllButtons 变量也在 all_buttons 变量变化时发生变化,所以它给了我错误:

Uncaught DOMException: Failed to execute 'add' on 'DOMTokenList': The token provided ('[object HTMLButtonElement]') contains HTML space characters, which are not valid in tokens.

我能做什么?

您应该只在数组中保存初始的 类。 这个有用吗?

var all_buttons = document.getElementsByTagName('button');

var defaultClasses = [];

for (let i = 0; i < all_buttons.length; i++) {
  defaultClasses.push(all_buttons[i].classList.value);
}

function buttonColorChange(buttonThis) {
  if (buttonThis.value === 'red') {
    buttonsRed();
  } else if (buttonThis.value === 'reset') {
    buttonColorReset();
  }
}

function buttonsRed() {
  for (let i = 0; i < all_buttons.length; i++) {
    all_buttons[i].classList = 'btn btn-danger';
  }
}

function buttonColorReset() {
  for (let i = 0; i < all_buttons.length; i++) {
    all_buttons[i].classList = defaultClasses[i];
  }
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

<div class="flex-box-pick-color">
  <form action="">
    <select name="backdrop" id="background" onchange="buttonColorChange(this)">
      <option value="random">Random</option>
      <option value="red">Red</option>
      <option value="reset">Reset</option>
    </select>
  </form>
  <button class="btn btn-primary">Whatever</button>
  <button class="btn btn-danger">Nothing</button>
  <button class="btn btn-warning">:)</button>
  <button class="btn btn-success">(:</button>
</div>

这对我有用

window.addEventListener("load", () => {

  const all_buttons = document.querySelectorAll('button');
  const copyAllButtons = [...all_buttons].map(but => but.classList.value)

  const buttonsRed = () => {
    all_buttons.forEach((but, i) => {
      but.classList.remove(...but.classList);
      but.classList.add("btn", "btn-danger");
    })
  };

  const buttonColorReset = () => {
    all_buttons.forEach((but, i) => {
      but.classList.remove(...but.classList);
      but.classList = copyAllButtons[i]
    })
  };


  document.getElementById("background").addEventListener("change", function() {
    if (this.value === 'red') {
      buttonsRed();
    } else if (this.value === 'reset') {
      buttonColorReset();
    }
  });

})
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

<div class="flex-box-pick-color">
  <form action="">
    <select name="backdrop" id="background">
      <option value="random">Random</option>
      <option value="red">Red</option>
      <option value="reset">Reset</option>
    </select>
  </form>
  <button class="btn btn-primary">Whatever</button>
  <button class="btn btn-danger">Nothing</button>
  <button class="btn btn-warning">:)</button>
  <button class="btn btn-success">(:</button>
</div>

完成

const
  colors = {
    red: ["btn", "btn-danger"],
    blue: ["btn", "btn-primary"],
    orange: ["btn", "btn-warning"],
    green: ["btn", "btn-success"]
  },
  keys = Object.keys(colors),
  random = () => keys[Math.floor(Math.random() * keys.length)],
  all_buttons = document.querySelectorAll('button');

document.getElementById("background").addEventListener("change", function() {
  all_buttons.forEach((but, i) => {
    but.classList.remove(...but.classList);
    if (this.value === "reset") but.classList = but.dataset.orgclass;
    else {
      const color = this.value === "random" ? colors[random()] : colors[this.value];
      but.classList.add(...color);
    }
  });
});
all_buttons.forEach(but => but.dataset.orgclass = but.classList.value)
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

<div class="flex-box-pick-color">
  <form action="">
    <select name="backdrop" id="background">
      <option value="reset">Reset</option>
      <option value="random">Random</option>
      <option value="red">Red</option>
    </select>
  </form>
  <button class="btn btn-primary">Whatever</button>
  <button class="btn btn-danger">Nothing</button>
  <button class="btn btn-warning">:)</button>
  <button class="btn btn-success">(:</button>
</div>