最近代碼中有個功能需要用到手動觸發鍵盤事件的功能,咱們的現有庫對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);
}
}
完整事例:
