Отлавливаем изменения в поле input

в 9:38, , рубрики: html, javascript, метки: ,

Перед одним моим знакомым встала задача отлавливать любые изменения полей формы в реальном времение (то есть не ожидая когда пользователь уберет фокус и сработает стандартное событие onchange). И он посетовав на жизнь, реализовал данное действие следующим образом:

setInterval(function(){
   $("#input")...
}, 30)

Решение через таймаут выглядит ну совсем костылем, тем более уже html5 используется во всю и я решил попробовать найти кроссбрайзерное решение, с помощью иментов.

Итак, начал я конечно с html5 ивента oninput, планируя в дальнейшем сделать фикс для ie < 9 и жить без проблем. Кстати рабочие примерчики, в которые можно потыкать лежат тут (Для простоты я использовал jquery).

$("input").on("input", function (e){
    do something...
});

И все было бы протсо идеально, если бы не одно но! В ie9 все работает на половину, то есть, при вводе букв — все хорошо, функция paste работает прекрасно, а вот любая попытка удаления символов ни к чему не приводит, будто мы и не изменяем поле. Ну да ладно (может проблема у них с этим oninput), ищем решение дальше.

$("input").on("propertychange", function (){
     if (event.propertyName.toLowerCase() == "value") {
          do something...
     }
});

У браузера от MS есть прекрасное событие onpropertychange, которое я как раз и решил использовать для старых версий IE и как мы можем видеть работает оно замечательно, главное не забыть проверить, что изменилось именно нужное свойство, так как ивент более глобальный и работает не только при изменении value у полей формы.
И на этом я мог бы завершить свой пост, если бы ie9 не порадовал тем же багом что и с oninput. Видимо господа из MS «накосячили» где-то в глубине логики.
Собственно тут уже остается мало решений, но все же использовать setInterval имхо худшее, ниже я привел на мой взгляд оптимальный вариант:

$("input").on("keypress keyup paste cut IE9EventFix", function (e){
     switch (e.type) {
          case "cut":
          case "paste":
               setTimeout(function(){
                    $(e.target).trigger("IE9EventFix");
               }, 1);
               break;
          default:
              do something...
              break;
     }
});

Собственно подводя итог, кроссбраузерным вариантом тут будет комплексное решение на основе всех трех примеров. Я себе позволил потратить 15 минут и написать небольшой плагинчик к jquery который реализует новый ивент inputUniversal, посмотреть его код можно тут, однако прошу учесть что клагин тут лишь для вида, основная задача статьи показать какие нативные ивенты есть в браузерах. Пример использования ниже:

$("input").on("inputUniversal", function (e){
    do something...
});
-------------------- OR ---------------------
$("input").inputUniversal(function(){
    do something...
});

Автор: Seldon

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js