Как сделать так, чтобы элемент щелкнул, прежде чем он скроется от родителя при расфокусировке

#javascript #html #css

Вопрос:

Я пытаюсь создать элемент простого поля поиска, я создал простой код javascript ниже.

Фильтр и фокус, как и ожидалось в коде, но когда я щелкнул по grandchild элементу, он ничего не изменил, как будто его даже не щелкнули. Элемент все еще там, кажется, что расфокусировка на <input> элементе произошла раньше, чем у слушателя grandchild . Есть ли способ, как сделать так, чтобы щелчок произошел первым, или задержать его при расфокусировке?

 String.prototype.isContain = function(trg) {
  return (getLength(this.toLowerCase().split(trg.toLowerCase())) > 1);
}

let fieldinput = document.querySelectorAll(".child-1")[0];
fieldinput.addEventListener("keyup", function() {
  let grandchild = document.querySelectorAll(".grandchild");
  for (let x in grandchild) {
    if (grandchild.hasOwnProperty(x)) {
      if (grandchild.innerHTML.isContain(fieldinput.value)) {
        grandchild[x].style.display = "block";
      } else {
        grandchild[x].style.display = "none";
      }
      grandchild[x].addEventListener("click", function() {
        console.log(grandchild[x].innerHTML); // this never executed
      });
    }
  }
}); 
 .parent {
  position: relative;
}

.parent .child-1 {
  padding: 10px;
}

.parent .child-2 {
  position: absolute;
  max-height: 0px;
  top: 100%;
}

.parent .child-1:focus .child-2 {
  max-height: 500px;
} 
 <div class="parent">
  <input class="child-1" type="text" placeholder="Focus Here">
  <div class="child-2">
    <div class="grandchild">Option 1</div>
    <div class="grandchild">Option 2</div>
    <div class="grandchild">Option 3</div>
  </div>
</div> 

Ответ №1:

Несколько вопросов

  • отсутствующий код
  • ненужное использование querySelectorAll, когда вам нужен только один элемент
  • создание вложенного прослушивателя событий — в настоящее время вы добавляете прослушиватель событий ко всем внукам для каждой нажатой клавиши
  • Несухой
 String.prototype.isContain = function(trg) {
  return this.toLowerCase().split(trg.toLowerCase()).length > 1;
}

document.querySelector(".child-1").addEventListener("input", function() {
  document.querySelectorAll(".grandchild")
    .forEach(grandChild =>  grandChild.hidden = !grandChild.innerHTML.isContain(this.value))
});
document.querySelector(".child-2").addEventListener("click", function(e) {
  const tgt = e.target.closest(".grandchild");
  if (tgt) console.log(tgt.textContent)
}); 
 .parent {
  position: relative;
}

.parent .child-1 {
  padding: 10px;
}

.parent .child-2 {
  position: absolute;
  max-height: 0px;
  top: 100%;
}

.parent .child-1:focus .child-2 {
  max-height: 500px;
}

.hide { display: none } 
 <div class="parent">
  <input class="child-1" type="text" placeholder="Focus Here">
  <div class="child-2">
    <div class="grandchild">Option 1</div>
    <div class="grandchild">Option 2</div>
    <div class="grandchild">Option 3</div>
  </div>
</div>