Alt-комбинации
Символы, которых нет на клавиатуре, можно вводить с помощью Alt + числовой код символа. Я же хочу использовать эту возможность для своих нужд, но столкнулся с заковыркой.
На keydown и keyup я отслеживаю состояние клавиши Alt. Также требуется отслеживать набор цифровых символов. Это можно сделать в keyup или keypress. В keypress можно непосредственно через код символа определить, что это за символ нажат. В keyup через скан-код можно понять, что нажата цифровая клавиша. Вот тут и начинаются заковырки. При использовании keyup я получаю нажатую последовательность символов, но проблема в том, что никакими силами и извращениями не получается отменить вставку символа в поле ввода (вставляется символ, которому соответствует набранная комбинация). Пробовал все: stopPropagation, e.cancelBubble (хоть они и не для этого), preventDefault, return false, e.charCode = e.keyCode = e.which = 0. Хоть и написано на w3schools, что событие отменяемо, но что-то как-то не гасится оно даже без использования Alt-клавиши... С другой стороны, если использовать keypress, то данное событие вообще не запускается, если нажата и удерживается Alt-клавиша, а вызывается лишь однократно, когда Alt отпускается и надо вводить символ по указанному коду... И не пойму, как обойти проблему... |
demoniqus,
Событие keyup отменяемо, и видимо вы это и делаете, просто не оно ведёт к появлению символа, а keypress. Варианты: 1 Мучиться с keypress 2 Удалять символ перед кареткой |
Я как то себе писал, можете под себя доработать. Вообще таких штук много.
<script> var KeyBoard = (function () { function KeyBoard() { this.activeKeys = []; this.events = {}; this.onKeyDown = this.onKeyDown.bind(this); this.onKeyUp = this.onKeyUp.bind(this); this.dropKeys = this.dropKeys.bind(this); this.initialize(); } KeyBoard.prototype.on = function (command, handler, context) { var keys = KeyBoard.getKeys(command); var eventName = KeyBoard.getEventName(keys); if (!this.hasEvent(eventName)) { this.events[eventName] = []; } this.events[eventName].push({ originCommand: command, eventName: eventName, handler: handler, context: context || window, keys: keys }); return this; }; KeyBoard.prototype.off = function (command, handler) { if (!command) { this.events = {}; return this; } if (!handler) { delete this.events[KeyBoard.getEventName(KeyBoard.getKeys(command))]; return this; } var eventName = KeyBoard.getEventName(KeyBoard.getKeys(command)); if (this.hasEvent(eventName)) { this.events[eventName] = this.events[eventName].filter(function (binned) { return (binned.handler !== handler); }); if (!this.events[eventName].length) { delete this.events[eventName]; } } return this; }; KeyBoard.prototype.trigger = function (command) { var eventName = KeyBoard.getEventName(KeyBoard.getKeys(command)); if (this.hasEvent(eventName)) { this.triggerNumberEvent(eventName); } }; KeyBoard.prototype.destroy = function () { this.activeKeys = []; this.off(); document.removeEventListener('keydown', this.onKeyDown); document.removeEventListener('keyup', this.onKeyUp); window.removeEventListener('focus', this.dropKeys); window.removeEventListener('blur', this.dropKeys); }; KeyBoard.prototype.dropKeys = function () { this.activeKeys = []; }; KeyBoard.prototype.triggerNumberEvent = function (eventName) { this.events[eventName].forEach(function (binned) { binned.handler.call(binned.context, binned); }); }; KeyBoard.prototype.initialize = function () { KeyBoard.createValidateKeuMap(); this.setHandlers(); }; KeyBoard.prototype.hasEvent = function (eventname) { return !!(this.events[eventname] && this.events[eventname].length); }; KeyBoard.prototype.setHandlers = function () { document.addEventListener('keydown', this.onKeyDown, false); document.addEventListener('keyup', this.onKeyUp, false); window.addEventListener('focus', this.dropKeys, false); window.addEventListener('blur', this.dropKeys, false); }; KeyBoard.prototype.onKeyDown = function (event) { this.addActiveKey(event.keyCode); var eventName = KeyBoard.getEventName(this.activeKeys); if (this.hasEvent(eventName)) { event.preventDefault(); this.triggerNumberEvent(eventName); } }; KeyBoard.prototype.addActiveKey = function (keyCode) { if (this.activeKeys.indexOf(keyCode) !== -1) { console.warn('duplicate key! ' + keyCode); } else { if (KeyBoard.validKeys.indexOf(keyCode) != -1) { this.activeKeys.push(keyCode); this.activeKeys.sort(KeyBoard.sort); } } }; KeyBoard.prototype.onKeyUp = function (event) { this.activeKeys = this.activeKeys.filter(function (code) { return (event.keyCode !== code); }); }; KeyBoard.getKeys = function (command) { return command.split("+").map(function (char) { var key = char.toLowerCase(); if (key in KeyBoard.keyMap) { return KeyBoard.keyMap[key]; } else { console.error('Неизвестная клавиша! ' + char); throw new Error('Неизвестная клавиша! ' + char); } }).sort(KeyBoard.sort); }; KeyBoard.getEventName = function (keys) { return keys.join('+'); }; KeyBoard.sort = function (a, b) { return a - b; }; KeyBoard.createValidateKeuMap = function () { for (var key in this.keyMap) { if (this.keyMap.hasOwnProperty(key)) { this.validKeys.push(this.keyMap[key]); } } }; KeyBoard.keyMap = { 'backspace': 8, 'tab': 9, 'enter': 13, 'shift': 16, 'ctrl': 17, 'alt': 18, 'pause_break': 19, 'caps_lock': 20, 'escape': 27, 'page_up': 33, 'page_down': 34, 'end': 35, 'home': 36, 'left': 37, 'up': 38, 'right': 39, 'down': 40, 'insert': 45, 'delete': 46, '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55, '8': 56, '9': 57, 'a': 65, 'b': 66, 'c': 67, 'd': 68, 'e': 69, 'f': 70, 'g': 71, 'h': 72, 'i': 73, 'j': 74, 'k': 75, 'l': 76, 'm': 77, 'n': 78, 'o': 79, 'p': 80, 'q': 81, 'r': 82, 's': 83, 't': 84, 'u': 85, 'v': 86, 'w': 87, 'x': 88, 'y': 89, 'z': 90 }; KeyBoard.validKeys = []; return KeyBoard; })(); new KeyBoard().on('ctrl+e', function () { alert('ctrl+e') }); </script> |
tsigel, спасибо за подсказку! Я что-то совсем уже позабыл, что когда-то в самом деле именно в keypress обнулял символы, которые не хочу вводить... Сейчас придумаю квадратно-звездчатый велосипед, который все сделает на ОК...
|
Часовой пояс GMT +3, время: 22:22. |