Javascript 显示与google chrome中键入的键盘字符不同的键盘字符

Javascript 显示与google chrome中键入的键盘字符不同的键盘字符,javascript,google-chrome,Javascript,Google Chrome,我正在开发一个javascript键盘,它试图让用户能够用各种非洲语言输入。目前,这在IE8和firefox中运行良好,但在google chrome中运行不好,我实际上一直在使用它。我想要完成的是,例如,在我的物理键盘上键入“q”(keyCode=113)并获得“ɛ”(keyCode=603)作为输出,但目前,我的代码在google chrome中没有任何功能。我的代码的相关部分如下: var k_layouts = {}; k_layouts.Akan = {88:390,113:603

我正在开发一个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中所寻求的目标?或者,我的方法中是否缺少一些东西?我很乐意得到任何帮助和想法。

如果不创建一个新的事件(正如您所观察到的,该事件并不普遍受支持),而是取消该事件并插入与该角色对应的映射角色,这将更容易打字

假设用户正在输入id为“ta”的文本区域,以下内容将在所有主要浏览器中处理该文本区域的键盘输入,并将
q
映射到
ɛ
和所有其他字符映射到“X”,以便于说明


注意IE中存在一些问题,Hi Tim Down,你的解决方案是完美的,有效的!我很感激。作为你的学生很高兴:p享受!没问题。这似乎是一个有趣的问题,最近我碰巧为另一个问题写了一半。恭喜!你发现了一个bug!还有
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;
    }
};