событие размытия запускается без причины?

У меня есть 2 элемента. Первый элемент имеет событие blur, а второй элемент имеет событие mousedown. Событие mousedown для второго элемента возвращает фокус первому элементу, но blur для первого элемента срабатывает по какой-то причине, даже если первый элемент не был сфокусирован перед mousedownингом второго элемента.

Почему это происходит? Является ли это (каким-то) желаемым поведением или это какая-то ошибка?

<!DOCTYPE html>
<html>
<head>
<title>Bug?</title>
</head>
<body>

<input type="text" />
<br /><br />
<button>Click me to focus on the input</button>
<br /><br />
<input type="text" />

<script type="text/javascript">
    document.getElementsByTagName('input')[0].addEventListener('blur', function(e){
        console.log('blur', e);
    });

    document.getElementsByTagName('button')[0].addEventListener('mousedown', function(e){
        console.log('mousedown', e);

        document.getElementsByTagName('input')[0].focus();
    });
</script>
</body>
</html>

https://jsfiddle.net/rsh5aopg/


person Community    schedule 29.06.2017    source источник
comment
Я ожидаю следующего поведения: mousedown (фокус на кнопке) -> функция меняет фокус (фокус на вводе) -> mouseup (фокус на кнопке => размытие ввода).   -  person Edwin    schedule 29.06.2017
comment
@ Эдвин прав, или так кажется. Ради интереса, почему вы используете mousedown, а не click?   -  person George    schedule 29.06.2017
comment
Я так не думаю... срабатывает мышь/после/размывания. События запускаются в порядке mousedown, blur, mouseup, click. Мне нужно сделать кое-что перед запуском размытия, поэтому я использую указатель мыши вместо щелчка. stackoverflow.com/questions/22867022/onblur-vs-onclick-timing< /а>   -  person    schedule 29.06.2017
comment
Я только что добавил событие mouseup ко второму элементу... оно срабатывает после размытия. Размытие не вызвано наведением мыши.   -  person    schedule 29.06.2017
comment
у вас есть два размытия, одно для ввода и одно для кнопки   -  person Edwin    schedule 29.06.2017
comment
Предполагается, что прослушиватель событий срабатывает только тогда, когда первый ввод размывается... Первый ввод не размывается, если вы просто нажимаете кнопку или если вы убедитесь, что второй ввод находится в фокусе, когда вы нажимаете кнопку. Первый ввод не должен вызывать срабатывание размытия, если он не сфокусирован до нажатия кнопки   -  person    schedule 29.06.2017
comment
добавьте прослушиватель событий focus к своей кнопке, и вы поймете. Кстати, все эти события являются событиями по умолчанию, и они уже существуют в компонентах.   -  person Edwin    schedule 29.06.2017
comment
Ясно... Итак, кнопка фокусируется браузером после срабатывания mousedown... Почему она не фокусируется до срабатывания mousedown?   -  person    schedule 29.06.2017
comment
это до mousedown. Если вы добавите событие фокуса к кнопке, вы получите следующее: focus->mousedown->blur(input)->focus->mouseup (*это только у вас еще нет фокуса на mousedown - если у вас есть фокус, то первый фокус отсутствует)   -  person Edwin    schedule 29.06.2017


Ответы (1)


Это не ошибка, последовательность событий такова:

mousedown
blur
mouseup
click

Когда вы нажимаете кнопку, срабатывает событие mousedown. Внутри этого слушателя вы фокусируете первый ввод. Естественно, после события mousedown происходит событие размытия. Это отвлекает внимание от первого ввода, и вы видите, как выполняется код прослушивателя размытия.

Вы можете либо добавить e.preventDefault() к событию mousedown, либо использовать либо mouseup, либо click, так как оба они происходят после размытия. В любом случае, первый вход по-прежнему будет иметь фокус, как вы хотите.

person Sven Writes Code    schedule 29.06.2017
comment
Независимо от точной реализации, я не понял, что браузер меняет фокус на щелкнутый элемент после нажатия мыши, но до нажатия мыши. Это не очевидно, но после некоторого размышления становится понятно, что фокус/размытие должны происходить вместе. Кроме того, ваш ответ решает эту проблему, не заставляя браузер фокусироваться на кнопке. Спасибо - person ; 29.06.2017
comment
e.stopPropagation() работает, если вы хотите, чтобы текущее событие функционировало в обычном режиме (поместите курсор в текстовый бот, установите флажок и т. д.) и хотите только остановить запуск других событий. - person ; 03.07.2017