Как создать тело по щелчку, но исключить определенный элемент и его дочерние элементы с помощью Javascript?

#javascript #addeventlistener

#javascript #addeventlistener добавить eventlistener #addeventlistener

Вопрос:

При присоединении прослушивателя событий щелчка к телу с помощью javascript, как вы пишете условные обозначения, которые срабатывают только в том случае, e.target если это не элемент, содержащий класс active или какой-либо из дочерних элементов этого элемента? Внутри есть дочерние элементы active , которые должны быть интерактивными. Аналогично тому, когда вы нажимаете в любом месте модала, он остается открытым, но в любом другом месте DOM он удаляется?

 document.body.addEventListener("click", e => {
    if (!e.target ...) {
       // trigger functions
    }
}
  

Ответ №1:

Один из способов добиться этого эффекта — прослушать щелчок, а затем выполнить цикл вверх по DOM от e.target всего пути до document.body .

По мере продвижения вверх проверяйте каждый элемент, чтобы увидеть, содержит ли он класс .active . Если это произойдет, вы можете завершить функцию с помощью break инструкции.

Это означает, что у вас все еще могут быть дочерние элементы, .active которые остаются интерактивными и будут реагировать на другие Event Listeners запускающие другие функции.

Рабочий пример:

 const myFunction = (e) => {

  let containsActiveClass = false;
  let reviewNode = e.target;
  
  while (reviewNode.nodeName !== 'BODY') {
  
    if (reviewNode.classList.contains('active')) {
      containsActiveClass = true;
      break;
    }
    
    reviewNode = reviewNode.parentNode;
  }
  
  if (containsActiveClass === false) {
    window.alert('You clicked! (But not on .active or any of its child elements.)');
  }
}

document.body.addEventListener('click', myFunction, false);  
 .container {
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: 180px;
  background-color: rgb(127, 127, 191);
  cursor: pointer;
}

.active {
  cursor: defau<
}

.active,
.inactive {
  position: relative;
  display: inline-block;
  flex: 0 0 120px;
  height: 120px;
  text-align: center;
  font-family: sans-serif;
  font-size: 14px;
  background-color: rgb(255, 0, 0);
}

.active div,
.inactive div {
  position: absolute;
  top: 30px;
  left: 30px;
  width: 60px;
  height: 60px;
  background-color: rgb(255, 255, 0);
}  
 <div class="container">
<div class="inactive">Inactive
<div>Inactive Child</div>
</div>

<div class="active">Active
<div>Active Child</div>
</div>

<div class="inactive">Inactive
<div>Inactive Child</div>
</div>
</div>  

Ответ №2:

Вы можете сопоставить его с помощью css selector

 document.querySelectorAll('div').forEach(elem=>{
 console.log(elem.id, elem.matches('.active, .active *'))
})  
 <div id=d1>
  <div id=d2 class=active>
    <div id=d3></div>
  </div>
  <div id=d4>
    <div id=d5></div>
    <div id=d6 class=active></div>
  </div>
</div>