最近代碼中有個功能需要用到手動觸發鍵盤事件的功能,咱們的現有庫對fireEvent的實現還比較單一,對鍵盤事件沒有作支持,就自己封了一個。但鍵盤事件的fire在各瀏覽器下實現不一樣,下面分別說明一下:
1. IE下沒什麼問題,創建事件對象、對對象的keyCode屬性賦值,然後再拋出來就行了:
evtObj = document.createEventObject(); evtObj.keyCode=keyCode el.fireEvent('on'+evtType, evtObj);
2. Firefox 需要通過document.createEvent創建KeyEvents對象,再通過initKeyEvent方法對事件對象初始化
evtObj = document.createEvent('KeyEvents'); evtObj.initKeyEvent( evtType, true, true, window, false, false, false, false, keyCode, 0 );
3. Chrome/Safari/Opera
通過document.createEvent創建UIEvents對象,初始化後再在該對象上掛載按鍵值,Chrome和Opera可以先將keyCode屬性delete掉後,再用Object.defineProperty方法重新爲它賦值:
delete evtObj.keyCode;
Object.defineProperty(evtObj,"keyCode",{value:keyCode});
但是這裏需要注意一點:Safari無法對對象的keyCode屬性進行操作,強制覆蓋裏還會報錯,解決方法是將鍵keyCode轉爲字符後掛在事件對象的key屬性上:
evtObj.key=String.fromCharCode(keyCode);
通過這種方式繞開safari的坑後,在事件觸發時的回調中再對keyCode進行一次適配即可:
var keyCode=evt.keyCode || evt.key.charCodeAt(0);
最後,封裝好的function大概就是這樣:
function fireKeyEvent(el, evtType, keyCode){ var evtObj; if(document.createEvent){ if( window.KeyEvent ) { evtObj = document.createEvent('KeyEvents'); evtObj.initKeyEvent( evtType, true, true, window, false, false, false, false, keyCode, 0 ); } else { evtObj = document.createEvent('UIEvents'); evtObj.initUIEvent( evtType, true, true, window, 1 ); delete evtObj.keyCode; if(typeof evtObj.keyCode === "undefined"){ Object.defineProperty(evtObj,"keyCode",{value:keyCode}); }else{ evtObj.key=String.fromCharCode(keyCode); } } el.dispatchEvent(evtObj); }else if(document.createEventObject){ evtObj = document.createEventObject(); evtObj.keyCode=keyCode; el.fireEvent('on'+evtType, evtObj); } }
完整事例: