浅谈JavaScript的事件(事件模拟)

  事件经常由操作或者通过浏览器功能触发,通过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();

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏代码世界

HTML DOM Event 对象

1572
来自专栏flutter开发者

[Flutter Widget] Wrap

在前面的文章中我们讲了很多Widget的用法,包括简单的Widget和复杂一点的布局,其实归根到底都是为了解决我们在界面布局上的需求,最近很多童鞋私信我Flut...

7085
来自专栏进击的君君的前端之路

React—表单及事件处理

1153
来自专栏hightopo

基于 HTML5 的 3D 工控隧道案例

1492
来自专栏向治洪

React Native之react-native-scrollable-tab-view详解

在React Native开发中,官方为我们提供的Tab控制器有两种:TabBarIOS和ViewPagerAndroid。TabBarIOS,仅适用于IOS平...

8456
来自专栏Google Dart

AngularDart Material Design 选项卡 顶

注意:为了获得高质量的用户体验,选项卡条的用户必须将焦点设置为新显示的内容,以便1)选项卡不保留焦点样式,2)屏幕阅读器可以计算已更改的内容。

1262
来自专栏从零开始学 Web 前端

从零开始学 Web 之 BOM(二)定时器

多次点击“摇起来”按钮的时候,timeId 的值会有多个,而停止的时候,只会清理最后一个值,其他的值对应的定时器没有清理。

1111
来自专栏cnblogs

bootstrap源码分析之Carousel

源码文件: Carousel.scss Carousel.js 实现原理: 隐藏所有要显示的元素,然后指定当前要显示的为block,宽、高自适应 源码分析: ...

2539
来自专栏owent

JQuery扩展插件--提示信息

https://github.com/owt5008137/SimpleMetro

581
来自专栏我分享我快乐

网站布局中的三种定位级

第1种定位级:块对象默认定位级 此定位级特点:块对象默认情况下跟据其出现顺序上下安排布局 下图中是用块对象默认定位级排列的一个大容器包着三个小容器: ? 第2种...

36814

扫码关注云+社区

领取腾讯云代金券