如何使用 Ionic 3 在 iOS 上的任何输入之外收听 keyup 事件
How to listen keyup events outside any input on iOS with Ionic 3
我的问题很简单,我想我知道答案,但如果我错了,那就太好了……
我想使用外部条码扫描器(像物理蓝牙键盘一样工作)来读取条码但在任何输入之外。
我编写了一段在 android 设备上运行良好但在 iOS 设备上没有任何反应的代码......
我会尽快完成,我在 «window» 上监听 «keyup» 事件,当我按下 «Enter» 键时,我发出条形码事件 …
我使用 RxJS 和 Observable fromEvent,一切都在 Android 设备上运行良好。
是 Safari WebView 的问题吗?
我记得我在网站上已经遇到过同样的问题,Safari 不会在不需要键盘的元素(输入、文本区域……)之外触发键盘事件
/**
* Outil pour traiter la lecture d'un codebarre par un lecteur physique
* Seuls les évènements claviers hors input sont récupérés
*/
export namespace LecteurCodebarrePhysique {
// L'évènement est-il dans un input ?
const inInput = (event) => {return event.target instanceof Element && event.target.nodeName.toLowerCase() === 'input'};
// La touche relachée est-elle un caractère ?
const isTextKey = (event) => {return !inInput(event) && event.key.length === 1};
// La touche relachée est-elle la touche entrée ?
const isEnter = (event) => {return !inInput(event) && event.keyCode === 13};
/**
* Observable émettant le codebarre lu par un lecteur physique
*/
export function codebarreLu(): Observable<{text: string, format: string}> {
// Observable initiale : évèrement clavier
const keyup: Observable<KeyboardEvent> = fromEvent(window, 'keyup');
return keyup.pipe(
// On ne garde que les touches représentant un caractère
filter(ev => isTextKey(ev)),
// On ne garde que la valeur du caractère
map(ev => ev.key),
// On «bufferise» en attendant la touche entrée
buffer(keyup.pipe(filter(ev => {
const enter = isEnter(ev);
if (enter) {
ev.preventDefault();
ev.stopPropagation();
}
return enter;
}))),
// Quand la touche entrée est relachée, on concatène les caractères
// Et on essaye de déterminer si c'es un EAN13 (13 caractères numériques)
map(chars => {
const codebarre = chars.reduce((code, char) => code + char, '');
const isEan13 = /\d{13}/.test(codebarre);
return {text: codebarre, format: isEan13 ? 'EAN_13' : 'INCONNU'};
})
);
}
}
在 Android 设备上,如果我订阅 observable 并读取任何输入之外的条形码,订阅内的代码将被调用。
在 iOS 台设备上,没有任何反应……
尤里卡!
如果其他人和我有相同的issue/need,我post在这里回答!是的我太客气了^^
我已经将事件的目标从 «window» 更改为 «document» 并且......等待它......它起作用了。
我的问题很简单,我想我知道答案,但如果我错了,那就太好了……
我想使用外部条码扫描器(像物理蓝牙键盘一样工作)来读取条码但在任何输入之外。
我编写了一段在 android 设备上运行良好但在 iOS 设备上没有任何反应的代码......
我会尽快完成,我在 «window» 上监听 «keyup» 事件,当我按下 «Enter» 键时,我发出条形码事件 …
我使用 RxJS 和 Observable fromEvent,一切都在 Android 设备上运行良好。
是 Safari WebView 的问题吗?
我记得我在网站上已经遇到过同样的问题,Safari 不会在不需要键盘的元素(输入、文本区域……)之外触发键盘事件
/**
* Outil pour traiter la lecture d'un codebarre par un lecteur physique
* Seuls les évènements claviers hors input sont récupérés
*/
export namespace LecteurCodebarrePhysique {
// L'évènement est-il dans un input ?
const inInput = (event) => {return event.target instanceof Element && event.target.nodeName.toLowerCase() === 'input'};
// La touche relachée est-elle un caractère ?
const isTextKey = (event) => {return !inInput(event) && event.key.length === 1};
// La touche relachée est-elle la touche entrée ?
const isEnter = (event) => {return !inInput(event) && event.keyCode === 13};
/**
* Observable émettant le codebarre lu par un lecteur physique
*/
export function codebarreLu(): Observable<{text: string, format: string}> {
// Observable initiale : évèrement clavier
const keyup: Observable<KeyboardEvent> = fromEvent(window, 'keyup');
return keyup.pipe(
// On ne garde que les touches représentant un caractère
filter(ev => isTextKey(ev)),
// On ne garde que la valeur du caractère
map(ev => ev.key),
// On «bufferise» en attendant la touche entrée
buffer(keyup.pipe(filter(ev => {
const enter = isEnter(ev);
if (enter) {
ev.preventDefault();
ev.stopPropagation();
}
return enter;
}))),
// Quand la touche entrée est relachée, on concatène les caractères
// Et on essaye de déterminer si c'es un EAN13 (13 caractères numériques)
map(chars => {
const codebarre = chars.reduce((code, char) => code + char, '');
const isEan13 = /\d{13}/.test(codebarre);
return {text: codebarre, format: isEan13 ? 'EAN_13' : 'INCONNU'};
})
);
}
}
在 Android 设备上,如果我订阅 observable 并读取任何输入之外的条形码,订阅内的代码将被调用。 在 iOS 台设备上,没有任何反应……
尤里卡!
如果其他人和我有相同的issue/need,我post在这里回答!是的我太客气了^^
我已经将事件的目标从 «window» 更改为 «document» 并且......等待它......它起作用了。