Добавление стиля во время события mousedown предотвращает фокусировку и события щелчка при вводе в FF
Первоначальная проблема, которую я пытаюсь решить, связана с тем, что Ripple.js препятствует фокусировке на элементе ввода в Firefox (все остальные браузеры в порядке).
Вот простая демонстрация пульсации в jsFiddle, которая сломается в FF.
А вот и сравнение бок о бок Chrome и FF
То, что это, кажется, вытекает, является прерыванием focus
а также click
события в FF, когда стиль ввода (или любого из его родителей) был обновлен во время mousedown
событие.
Вот простой MCVE в стековых фрагментов
document.getElementById('txt').addEventListener('mousedown', function (event) {
this.style.cssText = "position: relative;";
});
<input type="text" id="txt" />
Чтобы отладить это немного больше, мы можем регистрировать любые события, как это:
$("input").on("mousedown focus focusin mouseup click blur keydown keypress keyup change",function(e) {
console.log("{" + e.currentTarget.nodeName.toLowerCase() + ":" + e.type + "}");
});
Вот сравнение событий, возникающих при нажатии на <input>
в сценарии по умолчанию против после того, как мы сделали что-нибудь, чтобы изменить стили во время mousedown
событие в ФФ:
наблюдения
- Опять же, эта проблема только в Firefox, все остальные браузеры будут запускать
focus
событие. - Это происходит только для некоторых свойств CSS, таких как
overflow
или жеposition
, но нетcolor
, - Это происходит независимо от того, применяем ли мы эти изменения к самому элементу ввода или любому из его родительских элементов.
- Это происходит независимо от того, как мы вносим изменения в CSS, будь то непосредственно в JavaScript, через jQuery
.CSS()
или добавив класс, который содержит этот стиль.
Вот полнофункциональная демонстрация в jsFiddle и Stack Snippets, которая исследует некоторые наблюдения в предыдущем разделе
$("input").on("mousedown focus focusin mouseup click blur keydown keypress keyup change",function(e) {
console.log("{" + e.currentTarget.nodeName.toLowerCase() + ":" + e.type + "}");
});
//$(".wrapper").on("mousedown",function(){
$("input").on("mousedown",function(){
//$(this).addClass("relative")
//$(this).css("position","relative");
//$(this).css("overflow","hidden");
this.style.cssText = "position: relative;";
})
.relative {
position: relative;
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div class="wrapper">
<input type="text" />
</div>
Возможные обходные пути:
- Вы можете предварительно стилизовать элемент заранее, но для этого потребуется знать точно во время разработки, какие стили вы хотите применить во время выполнения
- Вы можете подождать позже в конвейере событий и прослушать
mouseup
событие, чтобы внести какие-либо изменения, но это не имеет такой же отзывчивости - Вы можете повторно применить фокус с
setTimeout
+.focus()
, но это минимально хакерский, а также трудно включить в большую библиотеку, когда эти предположения могут быть оспорены.
Примечание: я не рассматриваю эту конкретную проблему ни в одном из этих существующих вопросов о переполнении стека ( 1, 2, 3) для элементов ввода, не получающих фокуса событий щелчка в FF