转自:http://www.cnblogs.com/Random/archive/2013/03/29/2989789.html
最近代码中有个功能需要用到手动触发键盘事件的功能,咱们的现有库对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;<br>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); } } |
完整事例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>fireKeyEvent</title>
</head>
<body>
<input type="text" id="txt1"/>
<input type="button" id="btn1" value="fire"/>
<script type="text/javascript">
function $(id){
return document.getElementById(id);
}
function addEvent(el, type, fn){
if(document.addEventListener){
el.addEventListener(type, fn, true);
}else if(document.attachEvent){
el.attachEvent("on"+type, fn);
}else{
el["on"+type] = fn;
}
}
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);
}
}
addEvent($("txt1"), "keydown" ,function(e){
var evt=window.event || e;
var keyCode=evt.keyCode || evt.key.charCodeAt(0);
alert("keyCode:"+keyCode);
})
addEvent($("btn1"), "click", function(){
fireKeyEvent($("txt1"), "keydown", 27);
});
</script>
</body>
</html>