Cleave.js ориентирован на работу с DOM-событиями ввода и
преобразование пользовательского ввода в реальном времени. В основе
библиотеки лежит перехват событий input,
keydown, paste, а также обработка состояния
поля ввода через стандартный API HTMLInputElement.
Ключевой принцип совместимости заключается в том, что библиотека минимально зависит от современных API браузеров и опирается на относительно стабильные механизмы:
addEventListenerinput.valueОднако даже при такой консервативной модели возникают существенные различия в поведении браузеров, особенно при работе с мобильными устройствами, устаревшими движками и нестандартными режимами ввода.
Наиболее проблемная зона — старые версии Internet Explorer (IE10–IE11) и движки, близкие к ним по архитектуре.
Основные ограничения:
Отсутствие современных событий ввода в полной форме
input работает нестабильно в некоторых
сценариях удаления символовРазличия в поведении event.which и
event.keyCode
Проблемы с addEventListener в старых режимах
совместимости
Отсутствие поддержки Array.from,
Object.assign в нативной среде
Особенность IE заключается в том, что любые манипуляции со значением input могут приводить к потере каретки или некорректной перерисовке значения поля.
EdgeHTML (старый Microsoft Edge) демонстрирует поведение, близкое к IE, но с частичной поддержкой современных API.
Проблемные моменты:
selectionStart и
selectionEnd при автоматическом форматированииpaste событийCleave.js в таких условиях может создавать визуальные артефакты: скачки курсора, повторное форматирование строки, кратковременные неконсистентные состояния input.
Safari является одним из наиболее проблемных браузеров для библиотек маскирования ввода.
Основные причины:
Safari часто обновляет input.value не синхронно с
событием input, что приводит к ситуации:
Это вызывает некорректное форматирование при быстром наборе.
На мобильном Safari добавляются дополнительные ограничения:
keydowninput при использовании экранной
клавиатурыОсобенно критично:
Cleave.js вынужден часто пересчитывать позицию курсора, что в iOS не всегда возможно точно.
Safari иногда:
selectionStart = nullsetSelectionRange после
изменения DOMЭто напрямую влияет на корректность маскирования, особенно при форматировании телефонов и кредитных карт.
Chrome считается наиболее стабильной платформой для Cleave.js, однако и здесь есть тонкости.
При вводе азиатских языков (японский, китайский, корейский):
Cleave.js должен игнорировать промежуточные значения, иначе возникают:
Chrome может:
keydowninput.value напрямуюЭто приводит к тому, что Cleave.js не получает сигнал о изменении и не форматирует значение до следующего события.
Современные версии Chromium используют оптимизированные события ввода, где:
Это требует от Cleave.js повторной проверки состояния поля при каждом вызове обработчика.
Firefox отличается более строгой реализацией спецификации, но имеет собственные особенности.
В Firefox значение selectionStart чаще всего корректно,
однако:
Событие paste в Firefox:
inputЭто приводит к необходимости двойной проверки значения после вставки.
На мобильных устройствах проблема совместимости становится системной из-за внешнего управления вводом.
Особенности:
keydown событияПри использовании Cleave.js внутри Web Components возникают дополнительные ограничения:
querySelector не видит элементы внутри shadow root без
явного доступаcomposed: false)Это приводит к необходимости явно инициализировать Cleave.js на каждом input внутри shadow tree.
Хотя Cleave.js является DOM-ориентированной библиотекой, при интеграции в реактивные фреймворки появляются конфликты:
React может:
value после каждого рендераВ результате Cleave.js:
Это вызывает эффект дрожания input.
Vue отслеживает изменения через Proxy/Object.defineProperty:
В современных браузерах некоторые события помечаются как
passive, особенно на touch-устройствах.
Это влияет на:
preventDefaultCleave.js в таких условиях работает в более “наблюдательном” режиме, снижая уровень вмешательства в поток событий.
Дополнительная проблема совместимости связана не столько с браузерами, сколько с Unicode-реализацией:
value.length) не отражает визуальную
длинуЭто критично для масок, завязанных на фиксированную длину ввода (например, номера карт).
Поведение Cleave.js в разных браузерах формируется пересечением трёх факторов:
Из-за этого одна и та же логика форматирования может давать разные результаты в зависимости от окружения, даже при идентичном коде.