JavaScript | 事件

————————————————————————————————————————————

事件

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

文档或浏览器窗口中发生一些特定的交互瞬间,我们可以通过侦听器(或处理程序)来预定事件,以便事件发生的时候执行相应的代码

基本概念:

  • 事件类型(事件名字):说明发生什么类型事件的而字符串
  • 事件目标:事件目标是发生的事件或与之相关的对象,必须同时指定类型和目标。WindowDocumentElement对象是常见的事件目标,但某些事件也由其他类型的对象触发
  • 事件处理程序、事件监听程序:响应某个事件的函数被称为事件处理程序或事件侦听器
  • 事件对象:事件对象是与特定事件相关且包含有关该事件详细信息的对象,事件对象作为参数传递给事件处理程序函数。所有的事件对象都有用来指定事件类型的type属性和指定事件目标的target属性。每个事件类型都为其相关的事件对象定义一组属性。
  • 事件传播:浏览器决定哪个对象触发其事件处理程序的过程。

事件模型:

  • 内联模型:
    • 事件处理函数是HTML标签的一个属性,用于处理指定事件
  • 脚本模型:
    • JavaScript中处理事件,但无法同时处理多个相同的点击事件
  • DOM2模型:
    • "DOM2级事件"定义了两个方法,用于添加事件和删除事件处理程序的操作:addEventListener()removeEventListener()。所有DOM节点中都包含这两个方法,并且它们都接受3个参数;事件名、函数、冒泡或捕获的布尔值(true表示捕获,false表示冒泡)IE兼容性问题

调用事件三种模型写法

 1 <!DOCTYPE html>
 2 <html>
 3 
 4 <head>
 5     <title></title>
 6     <script type="text/javascript" src="test.js"></script>
 7 </head>
 8 
 9 <body>
10     <input type="button" value="test1" id="btn1">
11     <input type="button" value="test2" id="btn2">
12     <input type="button" value="test3" id="btn3">
13     <input type="button" value="event" id="btn4">
14 
15     <!-- 脚本模型 -->
16     <!-- 无法执行多个事件处理 -->
17     <script type="text/javascript">
18     // 获取id btn1的元素
19     var btn1 = document.getElementById('btn1');
20     // 监听当btn1产生onclick时事件
21     btn1.onclick = function test1() {
22         console.log('this is button 1.')
23     }
24 
25     // 另一种写法
26     var btn2 = document.getElementById('btn2');
27     // p.s.此处function不加(),否则将直接调用,onclick只能获得function返回值
28     btn2.onclick = test2;
29 
30     function test2() {
31         console.log('this is button 2.');
32         console.log(this.tagName);
33     }
34     var count = 0;
35     btn3.onclick = function() {
36         console.log(++count);
37         if (count == 3) {
38             // 当单击事件指向null时即为删除之前的事件
39             btn3.onclick = null;
40         }
41     }
42 
43     // 事件对象
44     // 在这里参数传的e即事件event,打印出来显示event类型
45     var btn4 = document.getElementById('btn4');
46     btn4.onclick=function(e){
47         // 在ie浏览器中需要这样 window.event;
48         var e = e||window.event; // 兼容所有浏览器的事件写法
49         console.log(e);
50     }
51 
52     </script>
53 </body>
54 
55 </html>

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

传统事件类型:

  • 鼠标事件
  • 键盘事件
  • 事件对象 Event IE兼容性问题
    • 常量
    • 属性
      • bubbles 返回布尔值,指示事件是否是起泡事件类型
      • cancelable 返回布尔值,指示事件是否可拥可取消的默认动作
      • currentTarget 返回其事件监听器触发该事件的元素
      • eventPhase 返回事件传播的当前阶段
      • target 返回触发此事件的元素(事件的目标节点)
      • timeStamp 返回事件生成的日期和时间
      • type 返回当前 Event 对象表示的事件的名称。
    • 方法
      • initEvent() 初始化新创建的 Event 对象的属性
      • preventDefault() 通知浏览器不要执行与事件关联的默认动作
      • stopPropagation() 不再派发事件。

targetcurrentTarget区别:

 1 <!DOCTYPE html>
 2 <html>
 3 
 4 <head>
 5     <title></title>
 6     <script type="text/javascript" src="EventUtil.js"></script>
 7 </head>
 8 
 9 <body>
10     <div id="box1" style="border:1px red solid;width:300px;height: 200px">
11         <input type="button" value="btn1" id="btn1" style="margin:10px">
12     </div>
13     <script type="text/javascript">
14     var btn1 = document.getElementById('btn1');
15     btn1.addEventListener('click', function(e) {
16         // currentTarget this target都指向这个button元素
17         console.log(e.currentTarget);
18         console.log(this);
19         console.log(e.target);
20         // 可以利用来修改样式
21         e.target.style.background = '#fff';
22     }, false);
23 
24     var box1 = document.getElementById('box1');
25     box1.onclick = function(e) {
26         console.log("div:" + e.currentTarget);
27         console.log("div:" + this);
28         console.log("div:" + e.target);
29     }
30 
31     document.body.onclick = function(e) {
32         console.log("body:" + e.currentTarget);
33         console.log("body:" + this);
34         console.log("body:" + e.target);
35     }
36 
37         var box1 = document.getElementById('box1');
38     document.onclick = function(e) {
39         console.log("document:" + e.currentTarget);
40         console.log("document:" + this);
41         console.log("document:" + e.target);
42     }
43     // target指向触发该事件的元素,currentTarget返回的是事件监听器触发的元素
44     // 当冒泡时候,点击btn1触发,在div监听器的target指向btn1,而currentTarget是div
45     </script>
46 </body>
47 
48 </html>

eventPhase

 1 <!DOCTYPE html>
 2 <html>
 3 
 4 <head>
 5     <title></title>
 6     <script type="text/javascript" src="EventUtil.js"></script>
 7 </head>
 8 
 9 <body>
10     <div id="box1" style="border:1px red solid;width:300px;height: 200px">
11         <input type="button" value="btn1" id="btn1" style="margin:10px">
12     </div>
13     <script type="text/javascript">
14     var btn1 = document.getElementById('btn1');
15     var box1 = document.getElementById('box1');
16 
17 
18     function handler(e) {
19         switch (e.type) {
20             case 'click':
21                 e.target.style.background = '#000';
22                 break;
23             case 'mouseover':
24                 e.target.style.background = 'yellow';
25                 break;
26             case 'mouseout':
27                 e.target.style.background = 'blue';
28                 break;
29         }
30     }
31     box1.onclick = handler;
32     box1.onmouseover = handler;
33     box1.onmouseout = handler;
34     btn1.onclick = function(e) {
35         console.log("1:" + e.eventPhase);
36     };
37     document.body.addEventListener('click', function(e) {
38         console.log("2:" + e.eventPhase);
39     }, true);
40     document.body.onclick = function(e) {
41         console.log("3:" + e.eventPhase);
42     };
43     // 如果在捕获阶段调用时,返回1
44     // target在目标上时,返回2
45     // 处于冒泡阶段时,返回3
46     // 当点击btn1时,btn返回2,body返回13
47     // 当点击div时,body返回13,此时target不为body所以不返回2
48     // 当点击body时,body返回2
49     </script>
50 </body>
51 
52 </html>
  • 目标事件对象
  • 框架/对象事件
  • 表单事件
  • 剪贴板事件
  • 打印事件
  • 拖动事件
  • 动画事件
  • 过渡时间
  • 其他事件
  • 事件监听对象
  • 文档事件对象
  • 鼠标/键盘事件对象

事件流:

  • 事件流描述的是从页面中接收事件的顺序
  • 当几个都具有时间的元素层叠在一起时,点击其中一个元素,所有的元素都会触发事件
  • 两种模式
    • 冒泡:从里往外逐个触发(主流浏览器、IE
    • 捕获:从外往里逐个触发(Netscape

    p.s.浏览器现在默认为冒泡模型,使用DOM2级模型的事件绑定机制才能手动定义事件流模式

冒泡事件流

 1 <!DOCTYPE html>
 2 <html>
 3 
 4 <head>
 5     <title></title>
 6     <script type="text/javascript" src="test.js"></script>
 7 </head>
 8 
 9 <body>
10     <div id="box1" style="border:1px red solid;width:300px;height: 200px">
11         <input type="button" value="btn1" id="btn1" style="margin:10px">
12     </div>
13     <script type="text/javascript">
14     // 冒泡形式事件流
15     // botton -> div -> body -> documentElement -> document
16     var btn1 = document.getElementById('btn1');
17     var box1 = document.getElementById('box1');
18     btn1.onclick = function() {
19         alert('botton onclick');
20     }
21     box1.onclick = function() {
22         alert('div onclick');
23     }
24     document.body.onclick = function(e) {
25         alert('body onclick');
26         // 取消冒泡(兼容模式)
27         // 如果ie取消冒泡模式为undefined说明是其他浏览器,则执行w3c取消冒泡
28         if (typeof e.cancelBubble == 'undefined') {
29             // w3c取消冒泡,取消冒泡后documentElement和document都无法冒泡显示
30             e.stopPropagation();
31         } else {
32             // ie冒泡
33             e.cancelBubble() = true;
34         }
35     }
36     document.documentElement.onclick = function() {
37         alert('documentElement onclick');
38     }
39     document.onclick = function() {
40         alert('document onclick');
41     }
42     </script>
43 </body>
44 
45 </html>

绑定事件和移除事件

 1 <!DOCTYPE html>
 2 <html>
 3 
 4 <head>
 5     <title></title>
 6     <script type="text/javascript" src="test.js"></script>
 7 </head>
 8 
 9 <body>
10     <div id="box1" style="border:1px red solid;width:300px;height: 200px">
11         <input type="button" value="btn1" id="btn1" style="margin:10px">
12     </div>
13     <script type="text/javascript">
14     var btn1 = document.getElementById('btn1');
15     var box1 = document.getElementById('box1');
16     // 通过绑定事件addEventListener时,同一个元素多个相同事件会按顺序执行
17     btn1.addEventListener('click', function() {
18         alert('a');
19     }, false);
20     var handler1 = function() {
21         alert('b');
22     }
23     btn1.addEventListener('click', handler1, false);
24     btn1.addEventListener('click', function(e) {
25         alert('button click');
26         // 取消冒泡
27         // var e = e || window.event;
28         // if (typeof e.cancelBubble == 'undefined') {
29             e.stopPropagation();
30         // } else {
31             // e.cancelBubble = true;
32         // }
33     }, false);
34     box1.addEventListener('click', function() {
35         alert('div click');
36     }, false);
37     document.body.addEventListener('click', function() {
38         alert('body click');
39     }, false);
40     document.documentElement.addEventListener('click', function() {
41         alert('documentElement click');
42     }, false);
43     document.addEventListener('click', function() {
44         alert('document click');
45     }, false);
46     // 移除事件处理moveEventListener
47     // p.s.事件处理函数只能调用相同的,哪怕写相同的匿名函数也不可以
48     btn1.removeEventListener('click', handler1, false);
49     </script>
50 </body>
51 
52 </html>

事件兼容: IE兼容性问题

  • 事件绑定:addEventListenerattachEvent
  • 事件移除:removeEventListenerdetachEvent
  • 获取事件对象:e.target window.event.srcElement
  • 阻止冒泡:e.stopPropagationwindow.event.cancelBubble
  • 阻止默认:e.preventDefaultwindow.event.returnValue

封装兼容事件后调用

 1 var EventUtil = {
 2     // 检测绑定事件
 3     addHandler: function(element, type, handler)
 4     // 传入事件元素,事件类型,执行程序
 5     {
 6         if (element.addEventListener) {
 7             element.addEventListener(type, handler, false);
 8         }
 9         // ie浏览器
10         else if (element.attachEvent) {
11             element.attachEvent('on' + type, handler); // 在ie浏览器事件要加上on
12         }
13         // 都不行的话使用DOM0模型,直接脚本模式执行
14         else {
15             element['on' + type] = handler;
16         }
17     },
18     removeHandler: function(element, type, handler) {
19         if (element.removeEventListener) {
20             element.removeEventListener(type, handler, false);
21         } else if (element.detachEvent) {
22             element.detachEvent('on' + type, handler);
23         } else {
24             element['on' + type] = null;
25         }
26     },
27     // 获得事件
28     getEvent: function(event) {
29         if (event) {
30             return event;
31         } else {
32             return window.event;
33         }
34         // return event?event:window.event;
35     },
36     // 获得Target
37     getTarget: function(event) {
38         return event.target || event.srcElement;
39     },
40     // 取消默认行为
41     preventDefault: function(event) {
42         if (event.preventDefault) {
43             event.preventDefault();
44         } else {
45             event.returnValue = false;
46         }
47     },
48     // 取消冒泡
49     stopPropagation: function(event) {
50         if (event.stopPropagation) {
51             event.stopPropagation();
52         } else {
53             event.cancelBubble = true;
54         }
55     },
56 }
 1 <!DOCTYPE html>
 2 <html>
 3 
 4 <head>
 5     <title></title>
 6     <script type="text/javascript" src="EventUtil.js"></script>
 7 </head>
 8 
 9 <body>
10     <div id="box1" style="border:1px red solid;width:300px;height:100px">
11         <input type="button" value="btn1" id="btn1">
12     </div>
13     <a href="./EventUtil.js" id="a1">取消默认链接</a>
14     <script type="text/javascript">
15     var btn1 = document.getElementById('btn1');
16 
17     function handler(e) {
18         // 获取事件
19         var e = EventUtil.getEvent(e);
20         console.log(e);
21         // 获取target,此处获取为btn1
22         var target = EventUtil.getTarget(e);
23         console.log(target);
24         console.log(target.tagName);
25     }
26     EventUtil.addHandler(btn1, 'click', handler);
27 
28     document.onclick = function() {
29         console.log('document click');
30     }
31     var box1 = document.getElementById('box1');
32     box1.onclick = function(e) {
33         console.log('box1 click');
34         // 取消冒泡
35         EventUtil.stopPropagation(e);
36     }
37 
38     var a1 = document.getElementById('a1');
39     a1.onclick = function(event) {
40         event = EventUtil.getEvent(event);
41         // 取消链接的默认行为
42         EventUtil.preventDefault(event);
43     };
44     </script>
45 </body>
46 
47 </html>

posted @ 2017-07-19 15:31  hugh.dong  阅读(294)  评论(0编辑  收藏  举报