2010-08-26 165 views
2

我的工作,旨在使用戶能夠在不同的非洲languages.Currently鍵入一個javascript鍵盤上鍵入的一個不同的鍵盤字符,這工作正常在IE8和Firefox,但不是谷歌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; 
    } 
} 

有沒有實現我所追求的鍍鉻做或一種方式,是有我丟失的東西在我的方法,我會很高興的任何幫助和任何想法。

+0

恭喜!你發現了一個錯誤! https://bugs.webkit.org/show_bug.cgi?id=16735和http://code.google.com/p/chromium/issues/detail?id=27048 – syockit 2010-08-30 04:29:38

回答

7

它會更容易不創建一個新的事件,正如你觀察到的是沒有得到普遍支持,而是取消事件,並插入對應輸入的字符映射字符。

假設用戶正在鍵入到一個textarea ID爲「TA」,下面將處理鍵盤輸入,用於在所有主要的瀏覽器的文本區域,映射到qɛ和所有其他字符「X」用於說明目的。

請注意,在IE < = 8中存在問題,其代碼用於找到用換行符執行的選擇,以下代碼爲簡潔起見未作處理。您可以在此處獲得我的跨瀏覽器功能,以便正確處理此問題: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; 
    } 
}; 
+0

喜添下, 您的解決方案是完美的,作品!我很感激。作爲你的學生很高興:P 享受! – ceblay 2010-08-27 16:56:15

+0

沒問題。這似乎是一個有趣的問題,我碰巧寫了大約一半的最近的另一個問題。 – 2010-08-27 22:50:08

+1

@ceblay那麼,爲什麼你不接受答案? – 2011-06-20 16:15:36