Как изменить свойство CSS с помощью JS DOM?

#javascript #html

#javascript #HTML

Вопрос:

 var toggleButton = document.getElementsByClassName('toggle-button')
for (var i = 0; i < toggleButton.length; i  ) {
  toggleButton[i].addEventListener('click', function () {
      toggleButton[i].parentElement.parentElement.children[2].style.background = "red";
  });
} 
 <div>
  <div>
    <button class="toggle-button">view</button>
  </div>

  <div>content</div>

  <div>the div which I want to apply changes on</div>
</div> 

Что не так с этим кодом?
Когда я запускаю его, он выдает мне эту ошибку «Uncaught TypeError: не удается прочитать свойство ‘parentElement’ неопределенного значения в HTMLButtonElement».

* Я не хочу применять изменения CSS к классу, мне нужно, чтобы они применялись к этому конкретному div с помощью DOM.

Комментарии:

1. Никогда не прикасайтесь к style атрибуту, и в более широком смысле: если вы хотите что-то сделать на стороне JS, используйте для этого API-интерфейсы JS, а не пытаться изменить «разметку» для элементов DOM. В этом случае вместо этого добавьте / переключите / удалите классы CSS, используя пространство имен element.classList , так что: toggleButtons.forEach(e => e.addEventListener("click", _event => e.classList.toggle("active"))) с классом CSS .active { background-color: red; } .

2. Он выдал эту ошибку «ToggleButton. forEach не является функцией »

3. Я сделал это так — var ToggleButton = document.getElementsByClassName(‘кнопка переключения’) кнопка переключения. forEach(e => e.addEventListener(«click», _event => e.parentElement.parentElement.children[2].classList.toggle(«активный»))) —

4. На самом деле ошибка здесь заключается i в обработчике щелчка: после цикла он будет 1 (или равен togleButton . длина), и нет кнопки переключения [1]. Использование this здесь имело бы больше смысла.

5. Извините, getElementsByClassName возвращает HTMLCollection, а не NodeList , поэтому вам нужно обернуть его в Array.from(...) get .forEach , что решает проблему i неправильного значения.

Ответ №1:

Если это всего лишь одна кнопка, разве вы не можете просто сделать это:

 const toggleButtons = document.getElementsByClassName('toggle-button')

toggleButtons[0].addEventListener('click', () => {
    toggleButtons[0].parentElement.parentElement.children[2].style.background = "red";
});
 

Или, если вы действительно хотите использовать цикл for по какой-то причине, для меня это работает просто отлично:

 var toggleButtons = document.getElementsByClassName('toggle-button')

for(let i=0; i<toggleButtons.length; i  ) {
  toggleButtons[i].addEventListener('click', function () {
    toggleButtons[i].parentElement.parentElement.children[2].style.background = "red";
  });
}
 

А еще лучше, создайте правило CSS для вызываемого класса red и используйте этот код для включения и выключения этого класса в выбранном div:

 var toggleButtons = document.getElementsByClassName('toggle-button')

for(let i=0; i<toggleButtons.length; i  ) {
  toggleButtons[i].addEventListener('click', function () {
    toggleButtons[i].parentElement.parentElement.children[2].classList.toggle('red')
  });
}
 

CSS:

 .red {
  background: red
}
 

Комментарии:

1. const toggleButtons = Array.from(document.getElementsByClassName('toggle-button')) а затем toggleButtons.forEach(e => ...) дает вам гораздо более надежный шаблон. Вам не нужно явно работать со счетчиком итераций.

Ответ №2:

Изменить getElementsByClassName на querySelectorAll('.toggle-button') , как показано ниже

 const toggleButton = document.querySelectorAll('.toggle-button')
for (let i = 0; i < toggleButton.length; i  ) {
  toggleButton[i].addEventListener('click', function () {
      toggleButton[i].parentElement.parentElement.children[2].style.background = "red";
  });
} 
 <div>
  <div>
    <button class="toggle-button">view</button>
  </div>

  <div>content</div>

  <div>the div which I want to apply changes on</div>
</div> 

Комментарии:

1. Примечание. Фактическое исправление здесь — это не извлечение узлов DOM, а тонкое изменение var i to let i в цикле, поэтому область действия и фактическое значение в обработчике щелчка.

Ответ №3:

Попробуйте использовать это таким образом, чтобы каждый прослушиватель событий ссылался на себя и backgroundColor

 var toggleButton = document.getElementsByClassName('toggle-button')
for (var i = 0; i < toggleButton.length; i  ) {
    toggleButton[i].addEventListener('click', function () {  this.parentElement.parentElement.children[2].style.backgroundColor = "red";
    });
} 
 <div>

    <div>
        <button class="toggle-button">view</button>
    </div>

    <div>content</div>

    <div>the div which I want to apply changes on</div>
    
</div>

<div>

    <div>
        <button class="toggle-button">view</button>
    </div>

    <div>content</div>

    <div>the div which I want to apply changes on</div>
    
</div>