Хотите меньше повторений при использовании JavaScript для изменения стилей по клику - PullRequest
1 голос
/ 13 июня 2019

Этот код в настоящее время работает, и при нажатии каждого элемента 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>

Хорошо, как я уже упоминал, код работает, но я бы просто стал слишком многословным, если чувствую его применение к большому проекту.Я относительно новичок в этом и хочу написать СУХОЙ - не повторяй себя - код.Спасибо!

Ответы [ 3 ]

0 голосов
/ 13 июня 2019

Если вы хотите, чтобы у трех элементов 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. Это также позволит вам добавить базовый стиль для общего класса вместо всех 3-х div.

0 голосов
/ 13 июня 2019

Вот некоторые изменения:

    1. Используйте одно и то же className для каждого блока и присвойте ему конкретное имя (т.е. box).
  • То же самое для добавленного className, проясните это.(т.е. is-selected).
  • Не дублируйте функции для одного и того же действия и используйте вместо этого 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>
0 голосов
/ 13 июня 2019

Вы можете сделать это довольно легко, просто пройдя через 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 относится к нажатому элементу

...