Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

scrollIntoView съедает следующий клик

Есть кастомный дропдаун (вообще на реакте, но это не важно).
Когда 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 #1
In #2
In #2
In #2
In #2
In #3
In #3
In #3
In #3
In #4
In #4
In #4
In #4
In #5
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 #1
In #2
In #2
In #2
In #2
In #3
In #3
In #3
In #3
In #4
In #4
In #4
In #4
In #5
In #5
In #5
In #5

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

Отправить комментарий