Как создать условие для события ‘click’ внутри / снаружи для нескольких divs?

#javascript

#javascript

Вопрос:

У меня есть html И js , как показано ниже :

 document.addEventListener('click', myFunction())

function myFunction(e) {
  let inputs = document.querySelectorAll('.my-element');
  let m = inputs.forEach((el) => el.contains(e.target));
  if (!m) {
    console.log('Element');
  }
}  
 <div class="my-element" style: "width:100px; height: 100px">
</div>
<div class="my-element" style: "width:100px; height: 100px">
</div>
<div class="my-element" style: "width:100px; height: 100px">
</div>  

Проблема в том, что условие работает, даже если я нажимаю внутри целевого объекта. Мне нужно, чтобы условие работало, только если я нажимаю за пределами элементов. В чем моя ошибка?

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

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

Ответ №1:

Если вы хотите, чтобы событие click запускалось, только если оно не над определенными элементами, вы должны проверить, не совпадает ли цель события с любым из этих элементов

У вас почти получилось, за исключением того, что вы устанавливаете значение m в значение forEach, которое всегда возвращает undefined, затем проверяете !m, которое всегда будет true

Просто создайте новый массив из списка узлов и установите m в .вместо этого найдите значение, так что в целом

 document.addEventListener('click', myFunction)

function myFunction(e) {
  let inputs = document.querySelectorAll('.my-element');
  let titles = document.querySelectorAll('.my-title');
  let m = Array.apply(0,inputs).find((el) => el.contains(e.target));
  if (!m) {
    console.log('Element');
  }
}

  

Ответ №2:

Здесь:

Поскольку inputs это список узлов, вам нужно преобразовать его в массив.

Я закончил здесь с оператором spread ...

Вы также можете сделать это с помощью Array.from , [].concat(inputs)

Затем вы фильтруете массив для своего e.target и проверяете, равна ли длина 0.

 document.addEventListener('click', myFunction)

function myFunction(e) {
  let inputs = document.querySelectorAll('.my-element');
  let m = [...inputs].filter(el => el === e.target);
  if (!m.length) {
    console.log('Element');
  }
}  
 <div class="my-element" style="background: black;margin: 10px;width:100px; height: 100px">
</div>
<div class="my-element" style="background: black;margin: 10px;width:100px; height: 100px">
</div>
<div class="my-element" style="background: black;margin: 10px;width:100px; height: 100px">
</div>  

Ответ №3:

Удалить () из myFunction в document.addEventListener('click', myFunction()) just use document.addEventListener('click', myFunction) .

Вы можете использовать Element.matches() with target as e.target.matches('.my-element') и убедиться, что это тот, который вы хотите. matches будет принимать selector как parameter .

Попробуйте в приведенном ниже примере, когда вы нажимаете на label или input это ничего не log даст. Когда вы нажмете другую часть, div тогда это произойдет log .

 document.addEventListener('click', myFunction);

function myFunction(e) {
  //let inputs = document.querySelectorAll('.my-element');
  //let titles = document.querySelectorAll('.my-title');
  //let m = inputs.forEach((el) => el.contains(e.target));
  if (e.target.matches('.my-element')) {
    console.log('Element', e.target.innerText);
  }
}  
 <div class="my-element" style: "width:100px; height: 100px">
  <label>abcd</label>
</div>
<div class="my-element" style: "width:100px; height: 100px">
<input type='text' value='input' />
</div>
<div class="my-element" style: "width:100px; height: 100px">c
</div>