如何更好更简单地写出这个问题?

3

我正在练习我的JavaScript技能,想出了一个当我点击它时可以在一组颜色中切换的按钮。

const button = document.querySelector('button');
const colours = ['red', 'yellow', 'green', 'blue'];
let cycle = 1;
button.style.backgroundColor = colours[0];
button.addEventListener('click', e => {

    button.style.backgroundColor = colours[cycle];
    cycle++;
    if (cycle == 4) {
        cycle = 0;
    };
});

if 可以改为 cycle %= 4; - Bergi
4个回答

2
您可以使用后置自增运算符和模运算符。此外,在事件回调中,您可以直接使用e.target代替button变量:

const button = document.querySelector('button');
const colours = ['red', 'yellow', 'green', 'blue'];
let cycle = 1;
button.style.backgroundColor = colours[0];
button.addEventListener('click', e => {
    e.target.style.backgroundColor = colours[cycle++ % colours.length];
});
<button>M</button>


1

你的解决方案非常好,很清晰。我可以向你展示如何在不使用循环变量的情况下仅使用颜色数组和数组函数来获取当前位置并将其增加。我使用颜色数组长度的余数来保持在数组大小内。

const button = document.querySelector('button');
const colours = ['red', 'yellow', 'green', 'blue'];
button.style.backgroundColor = colours[0]
button.addEventListener('click', e => {
    button.style.backgroundColor = colours[(colours.indexOf(button.style.backgroundColor)+1)%colours.length];
});
<button>Click me!</button>


谢谢,我认为我的应该看起来像这样。 - html.hayden

1
采用不同的、更加函数式的编程方式——你可以创建一个 cycleColours 函数,使用闭包返回一个可循环遍历颜色数组的函数。每次调用该函数,它都会返回数组中的下一个元素。
这种方式可以让你在其他地方重复使用该函数,并将逻辑与 button 点击处理程序分离。

const cycleColours = (coloursArray = []) => {
  const colours = coloursArray;
  let index = 0;

  const incrementIndex = () => {
    index++;
    if (index >= colours.length) index = 0;
  };

  return () => {
    const colour = colours[index];
    incrementIndex();
    return colour;
  };
};

const coloursButtonOne = ['red', 'yellow', 'green', 'blue']
const getButtonOneColour = cycleColours(coloursButtonOne);

const coloursButtonTwo = ['yellow', 'pink', 'purple', 'white']
const getButtonTwoColour = cycleColours(coloursButtonTwo);

const buttonOne = document.querySelector('button#one');
const buttonTwo = document.querySelector('button#two');

buttonOne.style.backgroundColor = getButtonOneColour();
buttonTwo.style.backgroundColor = getButtonTwoColour();

buttonOne.addEventListener('click', e => {
    e.target.style.backgroundColor = getButtonOneColour();
});

buttonTwo.addEventListener('click', e => {
    e.target.style.backgroundColor = getButtonTwoColour();
});
<button id="one">Click Me!</button>
<button id="two">Click Me!</button>


1
我还没有考虑过如何创建另一个按钮。谢谢。 - html.hayden

1
这是我的五分建议:
我的策略是:
  1. 尽可能使用CSS进行样式设置。避免使用内联样式或通过JavaScript设置样式。
  2. 不要直接向元素添加EventListeners。而是将EventListeners添加到文档中。使用事件冒泡。
  3. 封装变量名(这就是IIFE的作用)

// IIFE to encapsulate variable names
(function(w, d) {
  const className = 'color-cycle';
  const selector = `.${className}`;
  const cycles = 4

  // add EventListener to document not the element
  d.addEventListener('click', e => {
    // check the target of the event, if it is inside the button
    const button = e.target.closest(selector);
    if (button) {
      // Use `data-` attribute to store cycle
      button.dataset.cycle = (parseInt(button.dataset.cycle || 0) + 1) % cycles
    }
  });
}(window, document));

// For demonstration purposes
(function(d) {
  const selector = `#add-button`;
  const className = 'color-cycle';

  d.addEventListener('click', e => {
    const button = e.target.closest(selector);
    if (button) {
      const newButton = d.createElement('button');
      newButton.classList.add(className);
      newButton.textContent = 'Button'
      d.body.appendChild(newButton);
      d.body.appendChild(d.createTextNode("\n"))
    }
  })
}(document));
button {
  padding: 10px;
  border-radius: 10px;
  border: 1px solid gray;
  outline: none;
}

button:hover,
button:focus {
  border-color: black;
  border-width: 2px;
  padding: 9px;
}

button.color-cycle {
  display: inline-block;
  margin: 2px;
}
button.color-cycle,
button.color-cycle[data-cycle="0"] {
  background-color: red;
}

button.color-cycle[data-cycle="1"] {
  background-color: yellow;
}

button.color-cycle[data-cycle="2"] {
  background-color: green;
}

button.color-cycle[data-cycle="3"] {
  background-color: blue;
}
<button id="add-button">Add Button</button><br><br>

<button class="color-cycle">Button 1</button>
<button class="color-cycle">Button 2</button>
<button class="color-cycle">Button 3</button>
<button class="color-cycle">Button 4</button>


谢谢,我以前没有见过[data-cycle],一定会去了解一下。 - html.hayden
“cycle”是我发明的一个术语。在这一点上,你可以设置任何东西。 - yunzen
请参见:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/data-* - yunzen
请参阅 https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLOrForeignElement/dataset。 - yunzen
请参阅 https://developer.mozilla.org/zh-CN/docs/Web/CSS/Attribute_selectors。 - yunzen

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