【问题标题】:show different keyboard character from the typed one in google chrome显示与谷歌浏览器中键入的不同的键盘字符
【发布时间】:2010-08-26 20:28:19
【问题描述】:

我正在开发一个 javascript 键盘,旨在使用户能够输入各种非洲语言。目前,这在 IE8 和 firefox 中运行良好,但在 google chrome 中运行良好,我实际上被困在这个键盘上。我想要什么例如,输入(在我的物理键盘上)'q'(keyCode=113) 并获得 'ɛ'(keyCode=603) 作为输出,但是目前,我的代码在谷歌浏览器中没有任何作用。我的代码的相关部分如下:

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 中寻求做的事情?或者,我的方法中是否缺少某些东西?我很乐意提供任何帮助和想法。

【问题讨论】:

标签: javascript google-chrome


【解决方案1】:

不创建新事件会更容易,正如您所观察到的那样,该事件并未得到普遍支持,而是取消该事件并插入与键入的字符相对应的映射字符。

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

请注意,在 IE Is there an Internet Explorer approved substitute for selectionStart and 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;
    }
};

【讨论】:

  • 您好 Tim Down,您的解决方案非常完美且有效!我很感激。很高兴成为你的学生:P 享受!
  • 没问题。这似乎是一个有趣的问题,最近我恰好为另一个问题写了大约一半。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-28
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
  • 1970-01-01
  • 2015-09-30
相关资源
最近更新 更多