Есть кастомный дропдаун (вообще на реакте, но это не важно).
Когда 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;
}
In #1
In #1
In #1
In #2
In #2
In #2
In #3
In #3
In #3
In #4
In #4
In #4
In #5
In #5
In #5
Ответ
Похоже из-за того, что в момент клика двигается контент, отпуск клавиши мышки происходит в другом месте, что браузером не интерпретируется, как событие 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;
}
In #1
In #1
In #1
In #2
In #2
In #2
In #3
In #3
In #3
In #4
In #4
In #4
In #5
In #5
In #5
Комментариев нет:
Отправить комментарий