Добавление DOM-события к нескольким элементам и влияние на стиль дочерних элементов

#javascript #html #dom-events

#javascript #HTML #dom-события

Вопрос:

Я новичок в javascript и борюсь с одной проблемой, для которой не могу найти решение. У меня есть несколько divs с классом «details» с их дочерним «expander-bottom». Я хочу смоделировать ситуацию, когда всякий раз, когда я нажимаю на div «details», его дочерние элементы меняют высоту с 0 до 550 пикселей. Я знаю, как это сделать для одного элемента, используя идентификатор div, но я не хочу дублировать код, устанавливающий конкретный идентификатор для каждого элемента и назначающий ему функцию. Я хотел бы сделать это в нескольких строках, используя имя класса;

Вот код для двух divs:

 <div class="details">
        Details  
        <div class="expander-bottom" style="height: 0px;" onclick="clickDiv()">                              
              <div class="text-prices">
                  <h1>Prices:</h1> <br>
                  Small: 5$<br>
                  Medium: 7$<br>
                  Large: 10$
              </div>         
        </div>           
</div> 

<div class="details">
            Details  
            <div class="expander-bottom" style="height: 0px;" onclick="clickDiv()">                              
                  <div class="text-prices">
                      <h1>Prices:</h1> <br>
                      Small: 6$<br>
                      Medium: 8$<br>
                      Large: 11$
                  </div>         
            </div>           
</div> 
  

И мой код javascript для одного элемента, использующий id вместо class, так что, как вы можете видеть, мне также пришлось использовать идентификатор дочерних элементов:

 function clickDiv(){  
var a = document.getElementById("expander-bottom"); 
    if(a.style.height=="0px"){
        a.style.height = "550px";
    }
    else if(a.style.height>="0px"){
        a.style.height = "0px";
    }   
}   
  

И поэтому это работает для одного элемента, а чтобы заставить его работать для других элементов, мне нужно назначить определенный идентификатор для родительского и дочернего элементов и дублировать функцию столько раз, сколько элементов.

Я пытался использовать EventListeners, создавая код, подобный приведенному ниже:

 var parents = document.getElementsByClassName("details");
var childrens = document.getElementsByClassName("expander-bottom");
for(var i=0;i<parents.length;i  ){
    parents[i].addEventListener('click', function(){
        if(childrens[i].style.height=="0px"){
            childrens[i].style.height = "550px";
        }
        else if(childrens[i].style.height>="0px"){
        childrens[i].style.height = "0px";
        }
    }, false);
}
  

Но, похоже, это не работает. Возможно ли использовать прослушиватель событий DOM в тонком случае, чтобы заставить его работать, или любое другое лучшее решение?

Ответ №1:

Не могли бы вы, пожалуйста, попробовать приведенный ниже пример.

 const detailsElements = document.querySelectorAll(".details");
for (let i = 0; i < detailsElements.length; i  ) {
  detailsElements[i].addEventListener("click", function () {
    let child = this.querySelector('.expander-bottom');
    if (child.style.height == "0px") {
      child.style.height = "550px";
    }
    else if (child.style.height >= "0px") {
      child.style.height = "0px";
    }
  });
}  
 .details{
  height: 200px;
}  
 <div class="details">
        Details  
        <div class="expander-bottom" style="height: 0px;" >                              
              <div class="text-prices">
                  <h1>Prices:</h1> <br>
                  Small: 5$<br>
                  Medium: 7$<br>
                  Large: 10$
              </div>         
        </div>           
</div> 

<div class="details">
            Details  
            <div class="expander-bottom" style="height: 550px;">                              
                  <div class="text-prices">
                      <h1>Prices:</h1> <br>
                      Small: 6$<br>
                      Medium: 8$<br>
                      Large: 11$
                  </div>         
            </div>           
</div>   

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

1. Если ответ решает вашу проблему, можете ли вы, пожалуйста, проголосовать за него

2. Это решило мою проблему. пусть дочерний элемент = this . querySelector(‘.expander-bottom’); <<< эта строка, помещенная в нужное место, выполняет свою работу. Спасибо!

Ответ №2:

Попробуйте это:

 var parents = document.getElementsByClassName("details");
var childrens = document.getElementsByClassName("expander-bottom");
for(var i=0;i<parents.length;i  ){
    (function(i){
        parents[i].addEventListener('click', function(){
            if(childrens[i].style.height=="0px"){
                childrens[i].style.height = "550px";
            }
            else if(childrens[i].style.height>="0px"){
            childrens[i].style.height = "0px";
            }
        }, false);
    })(i)
}
  

также не забудьте закрыть свой класс div здесь <div class="details>

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

1. Да, я уже заметил отсутствие кавычек там 🙂 Но ваше решение работает не так хорошо.

2. проблема в том, что операторы var не ограничены областью действия блока, здесь помогает функция закрытия, но это можно легко решить с помощью оператора ES6 let, но, поскольку вы новичок, я думал, вы об этом не слышали

3. Я еще не слышал об этом. Я всего неделю назад перешел с C # на JS, так что я совершенно новичок. К сожалению, это все еще не работает. Как будто у меня не было доступа к атрибуту стиля, получающему элементы по имени класса, я думаю.