Добавление стиля во время события mousedown предотвращает фокусировку и события щелчка при вводе в FF

Первоначальная проблема, которую я пытаюсь решить, связана с тем, что Ripple.js препятствует фокусировке на элементе ввода в Firefox (все остальные браузеры в порядке).

Вот простая демонстрация пульсации в jsFiddle, которая сломается в FF.
А вот и сравнение бок о бок Chrome и FF

Chrome - Фокус ввода с Ripple 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

Вопрос: это ожидаемое поведение или есть лучший обходной путь?

0 ответов

Другие вопросы по тегам