zoukankan      html  css  js  c++  java
  • 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;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;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;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;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;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>

  • 相关阅读:
    【HDU 2093】考试排名(结构体水题)
    【HDU 2037】今年暑假不AC
    【HDU 1234】开门人和关门人(水题)
    【HDU 1005】Number Sequence
    第一篇博客——ACM之路!
    深度学习全家福
    搭建 keras + tensorflow
    MSCI 成份股 清单
    SK-Learn 全家福
    创业笔记 -- 网站正式对外运营
  • 原文地址:https://www.cnblogs.com/hughdong/p/7206055.html
Copyright © 2011-2022 走看看