Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
409 views
in Technique[技术] by (71.8m points)

javascript - show different keyboard character from the typed one in google chrome

I'm working on a javascript keyboard that seeks to enable users to type in various African languages.Currently, this works fine in IE8 and firefox but not google chrome, and I'm actually stuck on this one.What I want to accomplish is for example, to type(on my physical keyboard) 'q'(keyCode=113) and get '?'(keyCode=603) as the output but currently, my code does nothing in google chrome. The relevant portion of my code is as follows:

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;  
    }  
} 

Is there a way of achieving what I seek to do in chrome?Or, is there something I'm missing in my approach?I'd be glad for any help, and any thoughts.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It would be easier not to create a new event, which as you observed is not universally supported, and instead cancel the event and insert the mapped character corresponding to the character typed.

Assuming the user is typing into a textarea with id "ta", the following will handle keyboard input for that textarea in all the major browsers, mapping q to ? and all other characters to "X" for illustrative purposes.

Be aware that there are issues in IE <= 8 with the code for finding the selection to do with line breaks that the following code doesn't handle for the sake of brevity. You can get my cross browser function for handling this correctly here: 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("
").length - 1));
            textInputRange.select();
        }

        return false;
    }
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...