В каком порядке срабатывают события при нажатии на кнопку и почему
Что проверяют
Знаете ли вы, что один клик это цепочка из нескольких событий разной природы, и понимаете ли фазы распространения. Следом часто спрашивают, что изменится при нажатии с клавиатуры или пальцем.
Как отвечать
При клике мышью по кнопке порядок такой:
pointerdown, затемmousedown: браузер сначала шлёт событие указателя, потом совместимое мышиное;focusи всплывающийfocusin: фокус переходит на кнопку как действие по умолчанию дляmousedown. ВызовpreventDefault()вmousedownфокус отменит;pointerup, затемmouseup: отпускание кнопки, в том же порядке указатель и мышь;click: приходит после отпускания. Если нажали на одном элементе, а отпустили на другом, браузер отправитclickих общему предку;submit: если кнопка внутри<form>, её тип по умолчаниюsubmit, и форма отправится.
При двойном клике тройка mousedown, mouseup, click повторяется дважды, и только потом приходит dblclick. На сенсорном экране идут pointerdown, touchstart, pointerup, touchend, а мышиные события и click эмулируются после. С клавиатуры мышиных событий нет: Enter вызывает click на keydown, пробел на keyup.
Каждое событие проходит три фазы: погружение от window к цели, цель и всплытие обратно. Обработчик по умолчанию слушает всплытие, для погружения передают { capture: true }. На одном элементе обработчики вызываются в порядке регистрации. stopPropagation() останавливает путь по дереву, stopImmediatePropagation() ещё и остальные обработчики на том же элементе.
Сильный штрих: при реальном клике микрозадачи выполняются между обработчиками, а при программном el.click() только после всех, потому что вызов синхронный и стек не пуст.
Где спотыкаются
Говорят, что click «срабатывает в фазе всплытия». Событие проходит все фазы, всплытие по умолчанию выбирается лишь для обработчика.
Забывают, что тип кнопки по умолчанию submit, и не понимают, почему кнопка внутри формы перезагружает страницу.
Вешают логику на mousedown или mouseup и ломают управление с клавиатуры: click приходит при любом способе нажатия, а мышиные события нет.