使用JavaScript更改onclick样式时希望减少重复

时间:2019-06-13 19:29:13

标签: javascript html css dry

该代码当前有效,单击每个div时,背景颜色和字体大小将更改。另外,将删除已经单击的其他两个div之一的格式。问题在于,这最终将需要大量代码,我想远远超出了所需。我想知道如何减少重复。在这个例子中,只有三个div并不是什么大问题,但是我的实际项目将需要很多。

我尝试包括多个div,所以看起来像这样;

document.querySelector(".div2, .div1").classList.remove("styles");

但这似乎没有用。

const div1 = document.querySelector(".div1");
const div2 = document.querySelector(".div2"); 
const div3 = document.querySelector(".div3"); 

function makeBigDiv1 () {
  document.querySelector(".div1").classList.add("styles");
  document.querySelector(".div2").classList.remove("styles");
  document.querySelector(".div3").classList.remove("styles");
}

div1.addEventListener("click", makeBigDiv1);

function makeBigDiv2 () {
  document.querySelector(".div2").classList.add("styles");
  document.querySelector(".div1").classList.remove("styles");
  document.querySelector(".div3").classList.remove("styles");
}

div2.addEventListener("click", makeBigDiv2);


function makeBigDiv3 () {
  document.querySelector(".div3").classList.add("styles");
  document.querySelector(".div1").classList.remove("styles");
  document.querySelector(".div2").classList.remove("styles");
}

div3.addEventListener("click", makeBigDiv3);
.div1 {
  width:500px;
  height:100px;
  border: 2px solid black;
}

.div2 {
  width:500px;
  height:100px;
  border: 2px solid black;
}

.div3 {
  width:500px;
  height:100px;
  border: 2px solid black;
}

.styles {
  font-size: 50px;
  background-color: grey;
}
<div class="div1">One</div>
<div class="div2">Two</div>
<div class="div3">Three</div>

正如我所提到的,代码可以工作,但是如果应用于大型项目,它只会变得过于冗长。我对此比较陌生,想编写DRY-不要重复自己-代码。谢谢!

3 个答案:

答案 0 :(得分:0)

您可以轻松地做到这一点,只需遍历div。这是一个例子。您可以进行一些优化,但是您会想到

const div = document.querySelectorAll('.div');

for (var i = 0; i < div.length; i++) {
  div[i].addEventListener('click', function(event) {
    for (var j = 0; j < div.length; j++) {
      // remove styles class from all the div classes
      div[j].classList.remove("styles");
    }

    // add styles class only to the clicked item
    this.classList.add("styles");
  });
}
.styles {
  font-size: 50px;
  background-color: grey;
}
<div class="div">One</div>
<div class="div">Two</div>
<div class="div">Three</div>

this.classList.add("styles"); this是指被单击的项目

答案 1 :(得分:0)

如果您希望三个div具有共享样式,则可以一次设置所有样式。您还可以使很多点击功能可重复使用。这就是我要做的:

const elements = document.querySelectorAll("div")

function attachClickHandler(className) {
  return () => {
    document.querySelector(`.${className}`).classList.add('styles');
    
    document.querySelectorAll(`div:not(.${className})`).forEach(element => { element.classList.remove('styles') });
   }
}

elements.forEach(element => {
  element.addEventListener("click", attachClickHandler(element.className))
})
<html> 
    <head>
    <style>
        .div1, .div2, .div3 {
           width:500px;
           height:100px;
           border: 2px solid black;
        }
        .styles {
           font-size: 50px;
           background-color: grey;
         }
    </style>
    </head>
    <body>
        <div class="div1">One</div>
        <div class="div2">Two</div>
        <div class="div3">Three</div>
    <script>
    </script>
    </body>
</html>

在上下文中,您可能不想将事件侦听器添加到每个div,因此您可以将一个类添加到要使其成为可选对象的所有div中,然后按类名查找所有div,而不是查找所有div类型的对象。这也可以让您为共享类添加基本样式,而不是全部添加到3个div中。

答案 2 :(得分:0)

这里有一些变化:

    1. 为每个块使用相同的className,并为其指定一个特定的名称(即box)。
    1. 与添加的className相同,请明确说明。 (即is-selected)。
    1. 请勿重复执行同一操作的功能,而应使用forEach遍历每个框。

// Get all boxes
const boxes = document.querySelectorAll('.box');

// For each box
[...boxes].forEach(box => {
  // Attach an event click listener
  box.addEventListener('click', () => {

    // Add the `is-selected` className to the clicked one
    box.classList.add('is-selected');
    
    // Remove the `is-selected` className to all the others
    [...boxes].filter(el => el !== box).forEach(box => {
      box.classList.remove('is-selected');
    })
  });
});
.box {
  width: 500px;
  height: 100px;
  border: 2px solid black;
}

.box.is-selected {
  font-size: 50px;
  background-color: grey;
}
<div class="box">One</div>
<div class="box">Two</div>
<div class="box">Three</div>