事件经常由操作或者通过浏览器功能触发,通过JavaScript也可以触发元素的事件。通过JavaScript触发事件,也称为事件的模拟。
- DOM中事件模拟
可以document的createEvent方法创建event对象。这个方法接收一个参数,即表示要创建的事件类型的字符串。在DOM2级中,所有这些字符串都使用英文复数形式,在DOM3级中都变成了单数。这几个字符串如下:UIEvents,一般化的ui事件,鼠标事件和键盘事件都继承于该事件,在DOM3级中是UIEvent;MouseEvents,一般化的鼠标事件,在DOM3级中是MouseEvent;MutationEvents,DOM变动事件DOM3级是MutationEvent;HTMLEvents,html事件,没有对应的DOM3级。
在创建了event对象后,还需要使用与事件有关的信息对其进行初始化。每种类型的event都有一个对应的方法,为其传入一个参数就可以初始化事件对象。模拟事件的最后一步是触发事件,触发事件使用dispatchEvent方法,所有支持DOM事件的节点都支持该方法。调用dispatchEvent方法需要传入一个参数,即表示要触发事件的event对象。
创建鼠标事件对象,并为其指定必要的信息,就可以模拟鼠标事件。创建鼠标事件的对象方法是createEvent方法,传入的参数是MouseEvents。返回的event对象有一个initMouseEvent方法,用于指定与鼠标事件有关的信息。这个方法接收15个参数,分别与鼠标事件中典型的属性一一对应,属性如下:type,表示要触发的事件类型,如“click”;bubbles,是否支持冒泡,如true;cancelable,表示事件是否可以取消,如true;view,事件关联的视图,一般是document.defaultView;detail,与事件有关的详细信息,通常设置为0;screenX,事件相对于屏幕的x坐标;screenY,事件相对于屏幕的y坐标;clientX,事件相对于视口的X坐标;clientY,事件相对于视口的Y坐标;ctrlKey,表示是否按下了ctrl键,一般为false;shiftKey,表示是否按下了shit键,一般为false;metaKey,表示是否按下了meta键,一般为false;button,表示按下的是哪一个鼠标键,默认为0;relatedTarget,表示与事件相关的对象,在模拟mouseout和mouseover时使用。
对于需要模拟鼠标事件,一般只需要传递前3个参数。
1 var callback =function(event){ 2 console.log("1"); 3 } 4 EventUtil.addEvent(document.getElementById("btnadd"),"click",callback); 5 var evt = document.createEvent("MouseEvents"); 6 evt.initMouseEvent("click",false,false); 7 var btn =document.getElementById("btnadd"); 8 btn.dispatchEvent(evt);
通过上面的事件,我们就能触发btnadd元素的click事件。首先我们为元素绑定了click事件,这个事件需要用户操作才能触发。第5行通过createEvent创建了鼠标事件对象,通过initMouseEvent初始化了事件对象。然后通过元素的dispatchEvent方法来触发事件。
DOM2级中对键盘事件没有做出规范的规定。在DOM3级中对键盘事件有明确的定义。调用createEvent方法,传入KeyboardEvent能够创建键盘事件。返回的事件对象包含一个initKeyEvent的方法。这个方法的参数如下:type,事件类型,如keydown;bubbles,事件是否支持冒泡,如true;cancelable,事件是否可以取消,如true;view,事件的视图,一般为document.defaultView;key,表示按下键的键码;location,表示按下了哪里的键,0表示默认的主键盘,1表示左,2表示右,3表示数字键盘,4表示移动设备,5表示手柄;modifiers,空格分隔的修改键列表,如shift;repeat,按这个键的次数。
1 var txt=document.getElementById("inputtext"); 2 txt.focus(); 3 var evt =document.createEvent("KeyboardEvent"); 4 evt.initKeyboardEvent("keydown",false,false,document.defaultView,"a",0,"Shift",0); 5 txt.dispatchEvent(evt);
上面的代码模拟了keydown事件,同时按下shift键和a键。
可以通过JavaScript代码模拟鼠标事件、键盘事件、HTML事件和变动事件。同时也可以模拟自定义事件。
1 var add=document.getElementById("btnadd"); 2 EventUtil.addEvent(add,"myevent",function(ev){ 3 ev=EventUtil.getEvent(ev); 4 var target=EventUtil.getTarget(ev); 5 console.log(ev.type);//myevent 6 }); 7 var evt=document.createEvent("CustomEvent"); 8 evt.initCustomEvent("myevent",false,false,"hello"); 9 add.dispatchEvent(evt);
上面的代码通过createEvent方法创建了CustomEvent事件对象,也就是自定义事件对象,通过initCustomEvent初始化对象,最后触发myevent事件。第5行输出事件的类型为myevent,正是我们自定义的事件。
上面的创建模拟事件的方法在ie8以及ie8以下的浏览器中,并不支持。可以使用以下的代码来模拟事件。
1 var btn =document.getElementById("btnadd"); 2 EventUtil.addEvent(btn,"click",function(e){ 3 console.log("click"); 4 }) 5 var evt=document.createEventObject(); 6 btn.fireEvent("onclick",evt);
最后讲一下事件模拟中经常用到的一场景,比如需要下载一幅图片或者导出excel等,可以通过事件模拟来实现。
1 function downloadImg(){ 2 var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 3 var img = document.createElement("img"); 4 img.src="Font-Awesome-3.2.1/src/assets/img/fort_awesome.jpg"; 5 img.style.display="none"; 6 document.body.appendChild(img); 7 if (userAgent.indexOf("MSIE") > -1) { 8 var oPop = window.open(img.src,"","width=1, height=1, top=5000, left=5000"); 9 for(; oPop.document.readyState != "complete"; ) 10 { 11 if (oPop.document.readyState == "complete")break; 12 } 13 oPop.document.execCommand("SaveAs"); 14 oPop.close(); 15 16 } 17 else{ 18 19 var evt=document.createEvent("MouseEvents"); 20 evt.initMouseEvent("click",false,false); 21 var a=document.createElement("a"); 22 a.download="test.jpg"; 23 a.href=img.src; 24 a.dispatchEvent(evt); 25 } 26 } 27 downloadImg();