показать другой символ клавиатуры от набранного в Google Chrome - PullRequest
2 голосов
/ 27 августа 2010

Я работаю над клавиатурой javascript, которая позволяет пользователям печатать на разных африканских языках. В настоящее время это хорошо работает в IE8 и Firefox, но не в Google Chrome, и я на самом деле застрял на этом. Что я хочу выполнить, например, набрать (на моей физической клавиатуре) « q » (keyCode = 113) и получить « ɛ » (keyCode = 603) в качестве вывода, но в настоящее время, мой код ничего не делает в Google Chrome. Соответствующая часть моего кода выглядит следующим образом:

var k_layouts = {};  
k_layouts.Akan = {88:390,113:603};//keyCode mappings for Akan language    
k_layouts.Ga = {120:596,81:400};//keyCode mappings for Ga language  
var current_layout = "";  

//function that maps the keyCode of a **typed** key to that of the **expected** key    
function map_key_code(keycode){  
    if(k_layouts[current_layout] && k_layouts[current_layout][keycode])  
        return k_layouts[current_layout][keycode];  
    return keycode;  
}  

//function that actually changes the keyCode of a **typed** key to the **expected** value
function handle_keypress(ev){  
    var ev = ev || window.event;  
    if(ev.bubbles != null ||!ev.bubbles)  
     return true;  
    var target = ev.target || ev.srcElement;  
    var keyCode = window.event? ev.keyCode: ev.which;  
    if(keyCode == 0)  
    return true;  
    var newKeyCode = map_key_code(keyCode);  
    if(newKeyCode == keyCode)  
    return true;  
    if(target.addEventListener){ //for chrome and firefox  
    //cancel event  
    ev.preventDefault();  
    ev.stopPropagation();  
    //create new event with the keycode changed  
    var evt = document.createEvent("KeyboardEvent");  
    try{//for firefox(works fine)  
        evt.initKeyEvent("keypress",false,true,document.defaultView,ev.ctrlKey,ev.altKey,ev.shiftKey,ev.metaKey,newKeyCode,newKeyCode);  
}  
    catch(e){// for google chrome(does not work as expected)  
        evt.initKeyboardEvent("keydown",false,true,document.defaultView,ev.ctrlKey,ev.altKey,ev.shiftKey,ev.metaKey,newKeyCode,newKeyCode);  
    }  
    //dispatch new event  
    target.dispatchEvent(evt);  
    }  
    else if(target.attachEvent){// works for IE  
        ev.keyCode = newKeyCode;  
    }  
} 

Есть ли способ достичь того, что я стремлюсь сделать в Chrome? Или что-то мне не хватает в моем подходе? Я был бы рад любой помощи и любым мыслям.

1 Ответ

8 голосов
/ 27 августа 2010

Было бы проще не создавать новое событие, которое, как вы заметили, не всегда поддерживается, а вместо этого отменить событие и вставить сопоставленный символ, соответствующий набранному символу.

Предполагается, что пользователь печатаетв текстовое поле с идентификатором «ta», следующее будет обрабатывать ввод с клавиатуры для этого текстового поля во всех основных браузерах, отображая q в ɛ и все другие символы в «X» в иллюстративных целях.

Имейте в виду, что в IE <= 8 есть проблемы с кодом для поиска выбора, связанного с разрывами строк, который следующий код не обрабатывает для краткости.Вы можете получить кросс-браузерную функцию для правильной обработки здесь: <a href="/193242/suschestvuet-li-odobrennaya-internet-explorer-zamena-dlya-selectionstart-i-selectionend#193255"> Есть ли одобренные Internet Explorer заменители selectionStart и selectionEnd?

var charMap = {
    "q": "ɛ"
};

document.getElementById("ta").onkeypress = function(evt) {
    var val = this.value;
    evt = evt || window.event;

    // Ensure we only handle printable keys, excluding enter and space
    var charCode = typeof evt.which == "number" ? evt.which : evt.keyCode;
    if (charCode && charCode != 13 && charCode != 32) {
        var keyChar = String.fromCharCode(charCode);

        // Get the mapped character (default to "X" for illustration purposes)
        var mappedChar = charMap[keyChar] || "X";

        var start, end;
        if (typeof this.selectionStart == "number" && typeof this.selectionEnd == "number") {
            // Non-IE browsers and IE 9
            start = this.selectionStart;
            end = this.selectionEnd;
            this.value = val.slice(0, start) + mappedChar + val.slice(end);

            // Move the caret
            this.selectionStart = this.selectionEnd = start + 1;
        } else if (document.selection && document.selection.createRange) {
            // For IE up to version 8
            var selectionRange = document.selection.createRange();
            var textInputRange = this.createTextRange();
            var precedingRange = this.createTextRange();
            var bookmark = selectionRange.getBookmark();
            textInputRange.moveToBookmark(bookmark);
            precedingRange.setEndPoint("EndToStart", textInputRange);
            start = precedingRange.text.length;
            end = start + selectionRange.text.length;

            this.value = val.slice(0, start) + mappedChar + val.slice(end);
            start++;

            // Move the caret
            textInputRange = this.createTextRange();
            textInputRange.collapse(true);
            textInputRange.move("character", start - (this.value.slice(0, start).split("\r\n").length - 1));
            textInputRange.select();
        }

        return false;
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...