我正在尝试使用JavaScript在简单的Web应用程序中检测集成到手持Android设备中的条形码扫描仪的字符输入。由于大多数条形码扫描仪的行为类似于键盘楔形,因此我使用检测事件keypress
和/或keyup
来解释和处理字符输入。
我不希望字符输入填充文本输入,因此我已将事件处理程序分配给document
,但是,我知道我也可以将其分配给window
。
我完成任务的示例代码如下所示; 此示例不区分键盘输入和扫描仪输入,但我已经解决了这个问题。
var barcodeString = "";
$(document).keypress(function (event) {
// If character is carriage-return prevent submit.
if (event.which === 13) {
event.preventDefault();
}
// Append other characters to barcodeString.
barcodeString += event.key;
});
我的问题是许多设备根本不返回任何可读字符。当我使用event.keyCode
监控字符代码时,我收到两个代码:229和13.本文W3 keyCode in key events和此StackOverflow应答Is it OK to ignore keydown events with keyCode = 229?概述了229代码意味着输入监视器正忙。我只能假设这是因为:
有趣的是,如果我在将文本扫描到文本输入时检测到event.keyCode
,则会检测到两个字符代码:229和13,然后 然后将文本插入到文本输入中文字输入。
我试图实现的设备是由Handheld Group制造的Nautiz X2。而另一款Android设备,我无法识别其品牌,但使用不同的条码扫描软件似乎更为通用。
Handheld Group确实提供了一个JavaScript API,用于与手持式扫描仪进行交互。它的工作方式是为名为Kiosk Browser的自定义浏览器提供APK,并实现对扫描程序特定的JavaScript的解释。文档可以在这里找到(它非常短而且不长读):JavaScript Scanner Interface
更通用的Android设备能够“减慢”扫描仪上的字符输入,使扫描仪与第三方应用程序更兼容。看,切换此选项可以让我检测字符输入。虽然event.key
总是返回代码229(这次是从一个不可读的字符开始),但String.fromCharCode(event.which)
将在某种程度上解决问题(它不处理特殊字符)。 Nautiz X2无法在软件设置中“减慢”输入。
我考虑过的替代解决方法是将文本输入放在具有样式display: none
的网页上以隐藏它并使用JavaScript来持续关注输入。我可以尝试来监控onChange
并处理字符输入。我真的想避免这种做法。
我提出的解决方法看起来很糟糕,第一个不是设备独立的。我想知道是否有更好的地方从条形码扫描仪“转储”文本输入,所以我可以在我的应用程序中处理它?或者,是否有可以监视的事件来检测字符输入?
答案 0 :(得分:0)
我知道这已经很晚了,但是我在包括Zebra TC20和Chainway C71在内的一系列设备中都面临着类似的问题。经过大量搜索之后,我发现了Bob Jase的这个惊人的Codepen示例。他已经在代码中记录了他的解决方案,但出于存档目的,我将在此处重新发布。 link to his CodePen
他的解决方案使用隐藏元素将焦点从可见元素更改为焦点,从而隐藏了柔软的Android键盘。
// whenever the visible field gets focused
$("#visibleField").bind("focus", function(e) {
// silently shift the focus to the hidden select box
$("#hiddenField").focus();
$("#cursorMeasuringDiv").css("font", $("#visibleField").css("font"));
});
// whenever the user types on his keyboard in the select box
// which is natively supported for jumping to an <option>
$("#hiddenField").bind("keypress",function(e) {
// get the current value of the readonly field
var currentValue = $("#visibleField").val();
// and append the key the user pressed into that field
$("#visibleField").val(currentValue + e.key);
$("#cursorMeasuringDiv").text(currentValue + e.key);
// measure the width of the cursor offset
var offset = 3;
var textWidth = $("#cursorMeasuringDiv").width();
$("#hiddenField").css("marginLeft",Math.min(offset+textWidth,$("#visibleField").width()));
});
#hiddenField {
height:17px;
width:1px;
position:absolute;
margin-left:3px;
margin-top:2px;
border:none;
border-width:0px 0px 0px 1px;
}
#cursorMeasuringDiv {
position:absolute;
visibility:hidden;
margin:0px;
padding:0px;
}
#hiddenField:focus {
border:1px solid gray;
border-width:0px 0px 0px 1px;
outline:none;
animation-name: cursor;
animation-duration: 1s;
animation-iteration-count: infinite;
}
@keyframes cursor {
from {opacity:0;}
to {opacity:1;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click on the field and type (it should work even though the field isn't really focused):
<p />
<!-- must be a select box with no children to suppress the keyboard -->
input: <select id="hiddenField" />
<span id="fakecursor" />
<input type="text" readonly="readonly" id="visibleField" />
<div id="cursorMeasuringDiv" />
我希望这会有所帮助。再次感谢Bob的解决!