Есть кастомный дропдаун (вообще на реакте, но это не важно).
Когда input получает фокус, отображается выпадающий блок и делается подписка на capturing-стадию клика по документу. В этом обработчике проверяется, клик произошёл внутри области, или вне. Если вне, то дропдаун закрывается, а обработчик снимается.
Так всё работает. Проблема возникает при добавлении в код inp.scrollIntoView()
или ручном изменении scrollTop
контейнера: если следующий клик происходит по аналогичному интупу, то обработчик клика вообще не вызывается.
Функции вызываются как-то так:
focus #1 #1
focus #2 #2
click #1
close #1
click #2
close #2
https://jsfiddle.net/2qb5L7og/1/
for (let inp of document.querySelectorAll("input")) {
inp.addEventListener('focus', e => {
console.log("focus", e.target.value, inp.value)
var dd = inp.nextElementSibling
dd.style.display = 'block'
inp.scrollIntoView()
document.addEventListener('click', function close(e) {
console.log("click", inp.value)
if (e.target.closest("section") !== inp.parentElement) {
console.log("close", inp.value)
dd.style.display = ''
document.removeEventListener('click', close, true)
}
}, true)
})
}
* {
box-sizing: border-box;
}
main {
border: 1px solid red;
height: 11.4em;
overflow: auto;
}
section {
position: relative;
margin: 1em 1em 7em 1em;
border: 1px solid blue;
background: #8FF;
}
input {
cursor: pointer;
display: block;
width: 100%;
}
div {
position: absolute;
top: 100%;
left: -1px;
right: -1px;
display: none;
border: 1px solid green;
border-top: 0;
}
<main>
<section>
<input value="#1" readonly>
<div>In #1<br>In #1<br>In #1<br>In #1</div>
</section>
<section>
<input value="#2" readonly>
<div>In #2<br>In #2<br>In #2<br>In #2</div>
</section>
<section>
<input value="#3" readonly>
<div>In #3<br>In #3<br>In #3<br>In #3</div>
</section>
<section>
<input value="#4" readonly>
<div>In #4<br>In #4<br>In #4<br>In #4</div>
</section>
<section>
<input value="#5" readonly>
<div>In #5<br>In #5<br>In #5<br>In #5</div>
</section>
</main>
Похоже из-за того, что в момент клика двигается контент, отпуск клавиши мышки происходит в другом месте, что браузером не интерпретируется, как событие click
.
Я вижу два решения:
mousedown
.Пример с событием mousedown
.
for (let inp of document.querySelectorAll("input")) {
inp.addEventListener('focus', e => {
console.log("focus", e.target.value, inp.value)
var dd = inp.nextElementSibling
dd.style.display = 'block'
inp.scrollIntoView()
document.addEventListener('mousedown', function close(e) {
console.log("click", inp.value)
if (e.target.closest("section") !== inp.parentElement) {
console.log("close", inp.value)
dd.style.display = ''
document.removeEventListener('mousedown', close, true)
}
}, true)
})
}
* {
box-sizing: border-box;
}
main {
border: 1px solid red;
height: 11.4em;
overflow: auto;
}
section {
position: relative;
margin: 1em 1em 7em 1em;
border: 1px solid blue;
background: #8FF;
}
input {
cursor: pointer;
display: block;
width: 100%;
}
div {
position: absolute;
top: 100%;
left: -1px;
right: -1px;
display: none;
border: 1px solid green;
border-top: 0;
}
<main>
<section>
<input value="#1" readonly>
<div>In #1<br>In #1<br>In #1<br>In #1</div>
</section>
<section>
<input value="#2" readonly>
<div>In #2<br>In #2<br>In #2<br>In #2</div>
</section>
<section>
<input value="#3" readonly>
<div>In #3<br>In #3<br>In #3<br>In #3</div>
</section>
<section>
<input value="#4" readonly>
<div>In #4<br>In #4<br>In #4<br>In #4</div>
</section>
<section>
<input value="#5" readonly>
<div>In #5<br>In #5<br>In #5<br>In #5</div>
</section>
</main>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Всем привет! Делаю таблицу с товаром, в которой будет меняться количество товара и сумма заказаНа кнопку "купить" меняется ссылка подобным...
Нужно сделать запрет на ввод знака "минус" в поле inputСтраница написана с использованием JSF и Primefaces
отправляю POST запрос в строку поиска, и нужно получить страницу ответную например В поисковую строку StackOverFlow вбиваю TEST И получаю https://rustackoverflow