Enter при вводе через IME: как не отправить форму раньше
Если Enter отправляет сообщение раньше, чем пользователь закончил ввод через IME, отделите подтверждение состава текста от команды отправки. В собственном обработчике Enter учитывайте состояние composition и проверяйте поведение в целевых браузерах. Сохраните явную кнопку отправки: исправление не должно лишить пользователя возможности завершить и отправить текст.
Один Enter выполняет две разные задачи
При обычном наборе текста разработчик может ожидать от Enter команду «Отправить». При составном вводе та же клавиша используется для подтверждения выбранного варианта символов. Если обработчик реагирует только на название клавиши, он способен отправить сообщение в момент, когда человек ещё редактирует его содержание.
Такой сценарий разобран в руководстве GoogleChrome по IME-safe отправке. Проблема относится к собственным обработчикам Enter, в том числе у полей поиска и переименования. Нативное поведение формы без такого обработчика не следует автоматически считать тем же самым случаем.
Что показывает isComposing
По документации MDN, свойство KeyboardEvent.isComposing описывает, произошло ли событие внутри сессии composition — после её начала и до окончания. Это полезный сигнал для разведения ввода и команды. Но из определения свойства не следует одинаковый порядок всех связанных событий в каждом браузере и способе ввода.
Отдельно учтите compositionend: событие возникает и при завершении, и при отмене составления. Поэтому само окончание сессии не является просьбой отправить сообщение. Не превращайте его в автоматическую отправку: пользователь мог отменить выбор или продолжить редактирование.
Опишите состояния редактора до исправления клавиши
Учебный чат содержит поле, кнопку и правило Enter для обычной отправки. Ему нужны разные состояния: текст ещё составляется, составление закончилось, команда отправки принята, запрос выполняется. Не смешивайте их в одно значение «поле не пустое». Непустое поле может содержать незаконченный пользователем текст.
В веб-приложении определите единый путь отправки из кнопки и клавиатурной команды. В этом пути проверяются допустимость текста и текущее состояние операции. Защита от раннего Enter должна стоять до отправки, а не пытаться удалить уже принятый сервером фрагмент постфактум.
Таблица ожиданий для учебной формы
Это собственная приёмочная таблица. Она задаёт договор интерфейса, а не сообщает результаты испытания конкретных браузеров. Для поиска замените отправку сообщения на запуск запроса, сохранив различие между подтверждением ввода и командой.
| Действие | Состояние ввода | Ожидаемый смысл | Сетевой запрос | Отдельная проверка |
|---|---|---|---|---|
| Enter при выборе варианта IME | Составление ещё продолжается | Подтвердить ввод по правилам метода | Сообщение не отправляется | Текст остаётся доступен для дальнейшей правки |
| Обычный Enter после завершения ввода | Готовый текст, отправка разрешена | Команда отправки по договору чата | Один запрос через общий путь | Не остаётся второго нативного пути отправки |
| Команда переноса строки | Многострочный редактор | Добавить строку, если это предусмотрено | Нет запроса отправки | Сочетание описано пользователю и не мешает вводу |
| Нажатие кнопки после завершения текста | Готовый текст | Явная отправка | Один запрос с итоговым значением | Кнопка доступна клавиатурой |
| Отмена составления | Сессия закончилась без команды отправки | Вернуться к редактированию | Нет автоматического запроса из compositionend | Содержимое не очищается без решения пользователя |
| Повтор команды во время ожидания | Запрос уже выполняется | Не создавать случайный дубль | По согласованной защите от повтора | Сбой запроса сохраняет возможность исправить и повторить |
Проверьте все пути, которые могут запустить действие
Если обработчик клавиши остановил собственный вызов, но форма отправилась другим путём, исправление неполное. Рассмотрите встроенное поведение поля, обработчик формы, обработчик кнопки и обёртки компонента. В нужном месте должна оставаться одна осмысленная команда, а не несколько конкурирующих реакций на одно нажатие.
При этом не запрещайте Enter во всём приложении. Он нужен для выбора, подтверждения и других ожидаемых действий. Ограничение привязывают к конкретному полю, состоянию и назначению клавиши. В многострочном редакторе отдельно согласуют перенос строки: нельзя чинить раннюю отправку ценой невозможности набрать обычный абзац.
Совместимость проверяют сочетанием браузера и способа ввода
В руководстве GoogleChrome отдельно рассматривается поведение Safari и порядок доставки событий. Это причина проверять целевую среду, а не объявлять одно условие универсальным исправлением. Соберите воспроизведение: браузер, система, метод ввода, тип поля и фактическая последовательность событий на учебном тексте.
Если выбран запасной механизм для конкретной среды, испытайте его и на обычном вводе. Проверка keyCode или задержка после окончания composition без такого разбора способна заблокировать нормальную команду. Не копируйте произвольное число миллисекунд как обещание, что все быстрые и медленные устройства будут вести себя одинаково.
Что это меняет для React и готовых компонентов
Фреймворк не отменяет исходный смысл клавиатурного события. Найдите уровень, на котором компонент принимает решение отправлять, и убедитесь, что сведения о составлении доходят именно туда. Исправление внешнего контейнера может не подействовать, если вложенный редактор уже выполнил отправку самостоятельно.
Для чат-бота на сайте проверьте также сохранность черновика при сетевой ошибке. Это отдельное состояние от IME, но ранняя очистка способна скрыть результат проверки. Пользователь должен видеть свой завершённый текст и понимать, принят ли он системой, без необходимости набирать всё заново.
Как принять исправление на безопасных данных
- Создайте учебную форму и вымышленные сообщения. Укажите, какое действие ожидается от Enter, переноса строки и кнопки.
- Включите поддерживаемый метод составного ввода и подтвердите вариант Enter. Проверьте, что отправка не произошла раньше отдельной команды.
- Завершите составление, отредактируйте текст и отправьте его обычным предусмотренным способом. Сверьте итоговое содержимое и число запросов.
- Отмените составление и продолжите набор. Окончание сессии не должно само отправить или очистить сообщение.
- Повторите набор в целевых браузерах и используемых компонентах, включая мобильный вариант, если он входит в продукт.
- Проверьте клавиатурный доступ к кнопке, перенос строки, ожидание и отказ сети. Исправление IME не должно ломать эти пути.
Для мобильного приложения с общим сервисом сообщений нужен свой сценарий приёмки доступного метода ввода. Успех настольного браузера не подтверждает поведение виртуальной клавиатуры. В журнале проверки сохраняйте среду и наблюдаемые действия без реальной переписки пользователя.
Готовое исправление разделяет три события: человек закончил составлять текст, человек попросил отправить и система приняла запрос. Они могут происходить близко по времени, но не являются одной командой. Именно это различие нужно сохранить при смене компонента редактора или обработчиков формы.
Вопросы и ответы
Что проверять в keydown isComposing перед Enter?
Проверьте, не относится ли нажатие к ещё идущему составлению текста, и не допускайте ранней отправки по своему обработчику. Дополнительно испытайте финальное подтверждение и последующую обычную команду в целевой среде.
Как исправить раннюю отправку при isComposing в React?
Найдите обработчик, который действительно запускает отправку, и передайте ему нужное состояние ввода. Одновременно проверьте вложенный редактор и общий путь формы, чтобы другой обработчик не отправил запрос раньше.
Почему isComposing требует отдельной проверки в Safari?
Одного определения свойства недостаточно для подтверждения порядка событий в целевом браузере и IME. Воспроизведите подтверждающий Enter на учебном тексте и проверьте выбранную совместимость, не объявляя задержку универсальным решением.
Читайте также
Сканер отправляет форму вместо добавления товара: что менять
ПоддержкаПисьмо ушло через SMTP, но его нет в «Отправленных»
БезопасностьСпам через форму на сайте: как остановить без капчи
РазработкаФорма не отправляется: как показать ошибку пользователю
ПоддержкаSMTP не работает: почему сайт не отправляет письма