Ввод скан-кода — это операция, при которой сканер QR-кода или другое устройство используется для сканирования графического кода (штрих-кода или другого кода) и последующего распознавания его содержимого как текстового ввода. Сканирование кодов может снизить затраты, снизить частоту ошибок при вводе и повысить эффективность ввода. Общие сценарии включают экспресс-доставку, складирование и складирование.
Сканер кода можно рассматривать как специальную клавиатуру. После идентификации содержания графического кода он выводит код клавиши в виде ввода с клавиатуры. После успешного сканирования кода для идентификации содержимого будет запущено событие клавиатуры, которое на самом деле представляет собой процесс имитации клавиш клавиатуры. При срабатывании всех распознанных текстов будет запущено событие «onkeydown/onkeyup». «Ввод события» будет вызван автоматически.
Например, сгенерируйте штрих-код из цифр «123456» и один раз отсканируйте код, чтобы «быстро ввести 123456», а затем быстро введите клавишу «Ввод».
Поскольку сканирование связано с вводом с помощью сочетания клавиш, можем ли мы отличить сканер кода от клавиатуры? По обычным каналам судить невозможно, ведь это все события «клавиатурного ввода», и сканер кода их не различает.
Однако есть и способ отличить это — использовать интервал ответа на события клавиатуры. Как правило, интервал между непрерывным вводом нескольких символов обычными людьми на клавиатуре составляет более 30 мс, а интервал между вводами, запускаемыми сканером кода, обычно находится в пределах 10 мс. Поэтому мы можем судить о взломе по интервалу между несколькими нажатиями клавиш.
Обычно со сканированием кода для ввода значения проблем не возникает, но это будет затруднительно, если сканер кода подключен к компьютеру, а текущий компьютер не переключится на китайский метод ввода. Как говорилось ранее, сканирование кода эквивалентно «вводу символа с клавиатуры + вводу».
На самом деле вы можете сделать это, переключив текущий метод ввода компьютера на китайский, а затем смоделировав, что произойдет, когда при сканировании (вводе) значение штрих-кода будет «qwe1»?
Что вы получите, если в это время нажмете «1»?
Ответ — получить кусок китайца, а это явно не то, что мы ожидали.
Самый простой и рекомендуемый метод — разместить на странице подсказку, сообщающую пользователю: «Ввод здесь необходимо переключить на английский метод ввода, иначе результаты могут не оправдать ожиданий».
Если вы сможете убедить продакт-менеджера сделать это, то дальше читать не нужно, если нет, то продолжайте читать ниже;
метод 1) Используйте <input type="password" />
Вместо обычного поля ввода сделайте его невидимым и напишите видимый элемент (можно input) отображает его содержимое.
метод 2) Контролировать все входы keycode значение, сохраните значение «процесса» символов, сканированных сканером кода, проигнорируйте «окончательное» значение в поле ввода, а затем используйте сохраненное значение процесса в качестве окончательного результата сканирования.
Начну с вывода: это не сработает.
Почему это не работает? Поскольку здесь очень много подводных камней, они будут подробно описаны ниже для справки.
В этом решении используются два входа: один input[type=’password’] и один text[type=’input’]. Они перекрываются с помощью относительного позиционирования CSS. Text[type=’input’] виден внизу, а input[type=’password’] невидим вверху. Контролируя ввод input[type=’password’], значение синхронизируется с text[type=’input’] для отображения содержимого.
<input
type="password"
value={{value}}
onInput={(e) => {
setValue(`${e?.target?.value}`)
}}
/>
<input type="text" value="{{value}}" />
Для приведенного выше HTML-кода мы можем установить всю прозрачность input[type=’password’] на 0 (вы также можете установить прозрачность на 0 для его фона, границы и текста соответственно).
Потом начинаются проблемы Прежде всего, после установки стиля вы обнаружите очевидную проблему «пропадает курсор при наборе текста». Причина в том, что курсор после прозрачности также становится прозрачным, а text[type=’input’] не фокусируется.
Есть два пути решения этой проблемы: 1) Установите цвет фона input[type=’password’] на прозрачность 0 и установите цвет курсора отдельно.
background: transparent;
caret-color: #181818;
Это может решить проблему невидимости курсора, но после ее решения обнаруживается новая проблема. Из-за несовместимой ширины текста, наложенного на input[type=text] и input[type='password'], например «1» и «9», «1» и «*», «a» и «A». «Ширина у всех разная. Таким образом, позиция курсора, принадлежащая input[type='password'], не совпадает с позицией в конце фактического видимого содержимого. Например, несоответствующая ширина «A87» и «***» приводит к изменению позиции курсора. быть неуместным.
Решение:
1)настраивать leterspace。
2) будет input[type='text'] заменяется на ul>li,Затем зафиксируйте ширину каждого элемента настройки.
Благодаря двум вышеуказанным конфигурациям и последующей точной настройке ширины ширина может быть постоянной, и курсор естественным образом будет отображаться нормально.
Однако этот метод создает новые проблемы В результате получаются числа, которые редко отделяются от других символов, например чисел. 1 и 8 между, 8 и 9 Расстояние между ними будет разным;* * Ширина между * станет шире.
Попробуйте еще раз попытаться type[пароль] динамически вычисляет ширину, и ее ширина правильная ul Динамически рассчитанная ширина остается постоянной.
setPasswordInputWidth(!value ? 1 : strUlRef?.current.offsetWidth);
Но он по-прежнему не выровнен, поскольку, хотя ширина элементов одинакова, ширина текстового содержимого по-прежнему непостоянна.
Поэтому нам приходится иметь дело с input[type=password] настраивать text-align:right
。
Таким образом, положение элемента в конце курсора после настройки считается выровненным.
Однако проблема все равно остается, поскольку хотя текст в конце и выровнен, передняя часть и начало не выровнены. Это приводит к тому, что выбранная «тень» не совпадает с выбранным элементом.
Ни в коем случае, продолжайте пробовать второй метод
2) Пройти диапазон + CSS3 анимация
Имитация курсора вручную,Динамические настройки Ширина крайнего левого угла — это ширина видимого контента.
cursorRef.current.style.left = textRef.current.offsetWidth;
проверено,Этот метод возможен,Может решить проблему смещения курсора,Только проблема с выбором "Тени" осталась.,Нет хорошего способа.
Кроме того, после решения проблемы с курсором возникают новые проблемы.
Для ввода[type=password] появится запрос на автоматическое заполнение.
Это характеристика Браузера,Хотя по международным стандартам,Теоретически можно пройтинастраиватьautocomplete
Подождите, пока придут атрибутынастраивать Он не выполняет автоматическое заполнение。
Но каждый, кто это сделал, знает, что браузеры не соблюдают этот атрибут строго. Chrome Тем более не осуществимо.
поэтому,Хотя есть «много» решений,Говорят, что наладки скрыты password Да, есть разговор readonly Да, я пробовал, но это не работает.
Однако, хотя обычный метод не работает, после тестирования я обнаружил закономерность. Только если поле input[type=password] очищено, будет запрошен рекомендуемый пароль и значение учетной записи, как показано выше. Если в поле ввода есть значение, оно не будет отображаться.
Итак, у меня возникла идея: я добавил один или N пробелов перед вводом [тип = пароль], чтобы его нельзя было очистить. Затем, когда он отображается, он динамически фильтруется, а затем отображается. Хотя это немного хлопотно, это можно рассматривать как решение проблемы.
Я думал, что все кончено, но во время теста обнаружил новую проблему: input[type=password] не может выполнить ctl+c и ctl+x. Это также функция браузера, и, похоже, нет хорошего способа решить ее напрямую.
Однако, если вы внимательно подумаете, эту проблему также можно решить, отслеживая события клавиатуры вручную. Вам просто нужно учитывать щелчок правой кнопкой мыши для копирования, сколько символов выбрать, выбрать все или несколько, повлияет ли комбинация клавиш на ввод сканирования и т. д. Поскольку эта реализация все еще немного сложна, я не практиковал ее (решил отказаться от этого плана).
Кроме того, поскольку это поле ввода [тип=пароль], в адресной строке, когда оно находится в фокусе, будет дополнительный значок ключа, но это не является большой проблемой и находится в пределах допустимого диапазона.
。。。
На данный момент я написал длинный-длинный код и не знаю, появятся ли какие-то новые вопросы. Может быть, есть, может быть, нет. Однако независимо от того, есть ли какие-либо новые проблемы, простое решение известных выше проблем вызывает у меня нежелание продолжать. Дело не в том, что я ленив, а в том, что слишком сложное решение определенно не является хорошим решением.
Итак, в конце концов я решил отказаться от этого плана.
Поскольку решение с паролем не работает, мы можем попробовать только второй метод, который реализуется путем глобального мониторинга события onkeydown. onkeydown все еще сложнее и имеет некоторые подводные камни, но на самом деле он намного лучше предыдущего.
Основная идея этого плана
Прослушивание всего ввода на странице keycode значение, чтобы определить, является ли это вводом скан-кода.
Если это ввод сканирования кода, «обработанное» значение кода, сканированного пистолетом-сканером кода, будет сохранено, а «окончательное» значение в поле ввода будет проигнорировано.
Наконец, когда нажимается клавиша Enter, сохраненное значение процесса используется в качестве окончательного результата сканирования кода.
Основной код реализации выглядит следующим образом:
let timeStamp = 0;
const keydownHandle = (e) => {
// Использовать событие внутри timeStamp Время принятия решения меньше, чем 30 Является ли миллисекунда сканированием кода
const isScan = e.timeStamp - timeStamp < 30;
timeStamp = e.timeStamp;
const inputElement = scannerInputRef?.current;
if (!isScan) {
// Оставьте поле пустым, не сканируя QR-код.
processCodesRef.current = "";
}
if (e.keyCode === 13) {
if (isScan) {
// Заменить напрямую значением процесса
setValue(processCodesRef.current);
inputElement.value = processCodesRef.current;
}
} else if (
(e.keyCode >= 96 && e.keyCode <= 105) || // цифровая клавиатура
(e.keyCode >= 48 && e.keyCode <= 57) || // число
(e.keyCode >= 65 && e.keyCode <= 90) || // письмо
e.keyCode === xxx // Другие символы, поддерживаемые сканированием QR-кода
) {
processCodesRef.current += e.key;
}
};
Проверено тестами,Приведенный выше план не имеет явных недостатков.,Единственная обнаруженная проблема заключается в том, что при сканировании буквенно-цифрового кода с использованием метода ввода на китайском языке будут происходить некоторые процессы ввода и отображения на китайском языке. Но поскольку в конечном итоге мы заменим входной результат значением процесса, конечный результат все равно будет в порядке.
В то же время я видел в Интернете, что некоторые персонажи будут потеряны, но я никогда с этим не сталкивался.
Лично я считаю, что переключение на китайский метод ввода при сканировании кода можно рассматривать как «ненормальный» сценарий. Поскольку конечная функция в порядке, недопустимо наличие некоторых процессов ввода на китайском языке в середине.
ps: лучшего способа нет. Если сканирование кодов на сайте является очень частой операцией, рекомендуется дать подсказку на уровне продукта, чтобы пользователи могли переключиться на английский ввод.
Для сканирования ввода QR-кода теоретически необходимо сначала сосредоточиться на поле ввода. Однако для лучшего взаимодействия с пользователем мы можем использовать некоторые методы оптимизации, позволяющие пользователям нормально сканировать QR-коды даже без фокусировки.
Помимо элементов ввода, имеющих события фокуса на веб-страницах, сама веб-страница браузера также имеет события фокуса. Как и другие наши приложения для ПК, оно находится в фокусе при первом открытии. Когда браузер находится в фокусе, он может нормально получать «события клавиатуры» (но у нас нет элементов ввода, видимых пользователю).
Таким образом, есть две ситуации для обработки несфокусированных входных оценок. Одна из них заключается в том, что вся веб-страница не имеет фокуса. Эта ситуация является поведением на уровне системы, и мы не можем с ней справиться. Другой заключается в том, что сама веб-страница браузера находится в фокусе, а поле ввода не в фокусе. В этом случае еще можно что-то сделать.
Решение для ввода без фокуса:,Глобальный мониторинг
。
1) Веб-страница отслеживает глобальные «события клавиатуры». 2) Затем используйте «Интервальный взлом» и другие функции, чтобы определить, был ли он вызван сканером кода. 3) На основе этих характеристик определяется, что входное значение действительно является ожидаемым входным значением, а затем отображается в соответствующее поле ввода через JS.
Конечно, теперь, когда этот уровень достигнут, мы можем определить, какой код введен, на основе содержимого отсканированного «кода», а затем заполнить конкретное содержимое в соответствующее поле ввода на основе содержимого. Это также можно легко решить. проблема нескольких страниц на одной странице. Поле ввода автоматически сканирует код, чтобы вызвать фокус поля ввода.