Mr.*_* B. 26 javascript ajax jquery barcode-scanner angularjs
我希望能够通过手持式扫描仪扫描条形码并使用Javascript处理结果.
条形码扫描仪几乎像键盘一样工作.它输出扫描/翻译(条形码 - >数字)数据原始(对吗?).实际上我只需要捕获输出并继续.但是怎么样?
这是我想做的一些伪代码:
$(document).on("scanButtonDown", "document", function(e) {
// get scanned content
var scannedProductId = this.getScannedContent();
// get product
var product = getProductById(scannedProductId);
// add productname to list
$("#product_list").append("<li>" + product.name + "</li>");
});
Run Code Online (Sandbox Code Playgroud)
提前致谢!
Enr*_*ico 26
您的伪代码将无法正常工作,因为您无权访问扫描程序以捕获类似的事件scanButtonDown
.您唯一的选择是HID扫描仪,其行为与键盘完全相同.要区分扫描仪输入和键盘输入,您有两种选择:基于定时器或基于前缀.
基于定时器
扫描仪可能比使用键盘(明智地)更快地输入字符.计算接收击键的速度,并将快速输入缓冲到变量中以传递给您的getProductsId
函数.@Vitall写了一个可重用的jQuery解决方案来捕获条形码扫描器输入,你只需要捕获onbarcodescanned事件.
前缀为基础
大多数扫描仪可以配置为所有扫描数据的前缀.您可以使用前缀开始拦截所有输入,一旦获得条形码,就可以停止拦截输入.
完全披露:我是Socket Mobile,Inc.的顾问,负责制造手持式扫描仪.
小智 10
我有点晚了,但我根据这里的一些答案完成了这项工作。
let code = "";
let reading = false;
document.addEventListener('keypress', e=>{
//usually scanners throw an 'Enter' key at the end of read
if (e.keyCode===13){
if(code.length>10){
console.log(code);
/// code ready to use
code="";
}
}else{
code+=e.key;//while this is not an 'enter' it stores the every key
}
//run a timeout of 200ms at the first read and clear everything
if(!reading){
reading=true;
setTimeout(()=>{
code="";
reading=false;
}, 200);} //200 works fine for me but you can adjust it
Run Code Online (Sandbox Code Playgroud)
经过大量的研究和测试,对我来说最有效的方法是从条形码扫描仪捕获输入,而无需关注表单输入。收听keydown
和textInput
事件。
该textInput
事件就像paste
事件一样。然后,它具有完整的条形码数据。就我而言,我正在寻找UPC条形码。该e.preventDefault()
被插入一个形式输入防止条形码数据:
document.addEventListener('textInput', function (e){
if(e.data.length >= 6){
console.log('IR scan textInput', e.data);
e.preventDefault();
}
});
Run Code Online (Sandbox Code Playgroud)
我已经使用CipherLab IR扫描仪在Android 4.4和7.0上对此进行了测试。
收听keydown
事件的示例。在我的情况下,我可以假设只要表单输入未聚焦,用户就在扫描条形码。
let UPC = '';
document.addEventListener("keydown", function(e) {
const textInput = e.key || String.fromCharCode(e.keyCode);
const targetName = e.target.localName;
let newUPC = '';
if (textInput && textInput.length === 1 && targetName !== 'input'){
newUPC = UPC+textInput;
if (newUPC.length >= 6) {
console.log('barcode scanned: ', newUPC);
}
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您可以e.keyCode === 13
在keydown
事件侦听器中侦听而不是检查字符串的长度来确定扫描。
并非所有的红外扫描仪都会触发该textInput
事件。如果您的设备没有,则可以检查它是否发出类似以下内容的信号:
monitorEvents(document.body);
Run Code Online (Sandbox Code Playgroud)
在这里找到了这个监视技巧: 如何记录jQuery中某个元素触发的所有事件?
条形码扫描仪的工作原理几乎就像键盘一样。
这取决于型号。我用过的每一个都像键盘一样工作(至少就计算机而言)
它输出扫描/翻译的(条形码->数字)原始数据(对吗?)。
它输出键码。
Run Code Online (Sandbox Code Playgroud)$(document).on("scanButtonDown"
你可能想要keypress
,但不想要scanButtonDown
。
查看事件对象以确定按下的“键”。
要确定整个代码何时被扫描,您可能会得到一个“数据结束”键(可能是空格或回车),或者您可能只需要计算正在输入的字符数。
好的,这就是我的做法。我设置了扫描仪,以添加前缀(在我的情况下,我使用Ctrl + 2或ASCII代码002(控制代码),因此无法通过键盘轻松输入)和ENTER(可以随意如果您的条形码数据可能包含回车,请将其更改为在每次条形码扫描后使用Ctrl + 3或ASCII代码003之类的内容。在jQuery中,我捕获了keypress事件,并查找了前缀。然后,将所有内容捕获到一个字符串中,然后触发一个自定义事件,我的应用程序可以监听该事件。因为我要防止按键事件,所以用户可以在文本字段中扫描条形码,这可以触发事件而不会影响他们正在做的任何事情。
此外,每个条形码都有一个1位数的前缀,我们可以用来识别扫描条形码的类型。例子:
let barcodeRead = '';
let readingBarcode = false;
let handleKeyPress = (e) => {
if (e.keyCode === 2) {
// Start of barcode
readingBarcode = true;
e.preventDefault();
return;
}
if (readingBarcode) {
e.preventDefault();
if (e.keyCode === 13) { // Enter
readingBarcode = false;
const evt = $.Event('barcodeScan');
evt.state = {
type: barcodeRead.substr(0, 1),
code: barcodeRead.substr(1),
};
$(window).trigger(evt);
barcodeRead = '';
return;
}
// Append the next key to the end of the list
barcodeRead += e.key;
}
}
$(window).bind('keypress', handleKeyPress);
Run Code Online (Sandbox Code Playgroud)
由于有了这个前缀,我现在可以识别条形码的类型,并查看是否应在此页面上处理它。例:
$(window).bind('barcodeScan', (e) => {
if (e.state.type !== 'E') {
alert('Please scan your employee badge only!');
} else {
$('#employee-badge').val(e.state.code);
}
});
Run Code Online (Sandbox Code Playgroud)
尝试了所有解决方案,但没有达到预期效果。我在scan.js 上找到了最简单的解决方案,我有使用 Angular 8 的应用程序。
非常简单且良好的实施。
对于 Angular 8,我遵循以下步骤:
1.npm安装onscan.js --save
2.打开 angular.json,在脚本数组中添加一项作为“node_modules/onscan.js/onscan.min.js”
3.在组件类中,实现AfterViewInit接口
declare var onscan:any;
ngAfterViewInit(): void {
//Put focus to textbox and press scanner button
onScan.attachTo(document, {
suffixKeyCodes: [13], // enter-key expected at the end of a scan
reactToPaste: true, // Compatibility to built-in scanners in paste-mode (as opposed to keyboard-mode)
onScan: function (sCode, iQty) { // Alternative to document.addEventListener('scan')
console.log('Scanned: ' + iQty + 'x ' + sCode);
},
});
}
Run Code Online (Sandbox Code Playgroud)
最好的事情是扫描的文本出现在聚焦的文本框元素中
希望这有帮助。
小智 5
我也想使用 React 来分享这个主题,因为我在这方面遇到了很多困难。我认为大多数条形码扫描仪,如 Hanz Herdel 所说,以 ENTER 终止。就我而言,我发现将输入包装在表单中并捕获提交事件、防止默认值并检索输入的值更容易。
我更喜欢这种类型的方法,以便处理任何类型的条形码长度,而不是检查它的长度。
这是我在 React 中的处理方式:
import { useState } from "react";
export default function Modal() {
const [repairArticles, setRepairArticles] = useState([]);
function handleBarcodeInput(e) {
e.preventDefault();
const input = e.target.querySelector("input");
const value = input.value;
setRepairArticles((prev) => {
return (prev = [...prev, value]);
});
input.value = "";
}
return (
<div>
<form onSubmit={(e) => handleBarcodeInput(e)} >
<input id="barcode-input" />
<button type="submit" className="hidden" />
</form>
<div className="mt-3">
{repairArticles.map((el, index) => {
return <p key={index}>{el}</p>;
})}
</div>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
60451 次 |
最近记录: |