问题
I'm trying to process input from a barcode scanner in a javascript browser app. The scanner output is a string of characters, which also contains at least one Group Separator character (ASCII 29).
When I direct the input to i.e. notepad++, the input is displayed correctly including the Group Separator characters. When I direct the input into a <input type="text">
html field, the Group Separator objects are lost; it's neither visible in the field, nor detectable with javascript code.
Does the <input type="text">
object truncate ASCII control characters? Any idea how to avoid that?
Edit: I'm using a code similar to Raidox's answer to achieve this:
inputField.onkeypress = catchGroupSeparatorAndEnter;
var fncChar = String.fromCharCode(29);
function catchGroupSeparatorAndEnter(event) {
if (event.ctrlKey && event.which === 29) {
inputField.value = inputField.value + fncChar;
event.preventDefault();
event.stopPropagation();
}
...
}
This seems to work in Chrome and Edge, but not in Firefox. I have no clue how to get it to work there.
回答1:
I've been struggling with this at work for the past week as well, and I finally made a breakthrough today. I don't know how your barcode scanner works, but ours acts like a USB keyboard and sends individual keypresses. It does send the keypress for [GS], but the event is automatically canceled by the browser. Therefore it never reaches the input event, which is the event that adds the character to your input. I couldn't figure out a way to prevent it from canceling, but you can get around this by adding the character to the input manually in the keypress event.
I don't know what framework you are working with for your application, but I was able to get this to work with AngularJS by building this into a custom directive. The example below is just vanilla JavaScript, but you should be able to implement it into any framework that you may be using.
Vanilla JavaScript Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Control Character Test</title>
</head>
<body>
<input type="text" id="tacos" />
<script>
document.getElementById('tacos').addEventListener('keypress', function(e) {
if (e.charCode === 29) {
this.value += String.fromCharCode(e.which);
}
});
</script>
</body>
</html>
You can save the code above into an HTML file to test if this approach works with your barcode scanner. If this doesn't work as is, another possibility worth exploring is reprogramming your barcode scanner to send every keypress, and then this approach should work.
Another Relevant Behavior
In my research, I also figured out that inputs do accept these characters if they are sent with other characters at the same time. For example, we have another barcode scanner that sends the barcode data as one event. The browser accepts this input with the [GS] character. You can also do this with copy/paste. You could potentially exploit this behavior to get what you want as well.
Browser Problems
It is worth keeping in mind that you might also run into problems with either of these approaches because of the browser you are using. Our barcode scanner that sends the data all at once is an android device. It has 2 browsers on it, chromium and a proprietary browser. The [GS] character shows up in chromium, but not the proprietary browser.
Hope this helps!
回答2:
Inspired by Sebastian G, this option allows to catch all Alt
+ number
codes.
This doesn't work on IE however.
var altvalue = '';
document.getElementById('scanfield').addEventListener('keydown', function (e) {
if (e.altKey) {
if (e.keyCode !== 18 /* ALT key */) { altvalue += e.key; }
}
});
document.getElementById('scanfield').addEventListener('keyup', function (e) {
if (e.altKey === false && altvalue != '') {
this.value += String.fromCharCode(parseInt(altvalue));
altvalue = '';
}
});
回答3:
The input control ignores non printable characters like [GS]
However, a barcode scanner usually emulates this character with CTRL+], which can be captured with the onkeydown event (key codes 17 and 221):
var ctrlPressed = false;
yourInput.addEventListener('onkeydown', function (event) {
ctrlPressed = 17 === event.keyCode;
if (221 === event.keyCode && ctrlPressed)
// do what you want here (ie. modify the input value)
});
If this does not work you may want to check the codes first by logging them:
yourInput.addEventListener('onkeydown', function (event) {
console.log(event.keyCode)
});
回答4:
I had the same problem and based on the idea with the event listener I build custom solutions for IE/Chrome and Firefox:
IE + Chrome (Raidox solution):
document.getElementById('scanfield').addEventListener('keypress', function(e) {
if (e.which === 29) {
this.value += String.fromCharCode(e.which);
}
});
Firefox:
var altValue = '';
document.getElementById('scanfield').addEventListener('keypress', function(e) {
if(e.altKey){
altValue += String.fromCharCode(e.which)
if(altValue == '0029'){
this.value += String.fromCharCode(29);
altValue='';
}
}
});
Edge works out of the box.
回答5:
Firefox doesn't transmit ALT keypress, but only keydown and keyup events.
This work for me in each browser:
//GS1 Datamatrix <GS> in Firefox, Chrome & IE
var altValue = '';
document.getElementById('SKAN').addEventListener('keydown', function(e) {
if(e.altKey){
if(e.which != 18){
altValue += e.which
}
if(altValue === '969698105'){
this.value += String.fromCharCode(29);
}
}
});
document.getElementById('SKAN').addEventListener('keyup', function(e) {
if(e.altKey === false){
altValue = '';
}
});
来源:https://stackoverflow.com/questions/48296955/ascii-control-character-html-input-text