(92)Wangdao.com_第二十五天_事件 Event

1. 事件 Event

事件的本质是: 程序各个组成部分之间的一种通信方式,也是 异步编程 的一种实现

DOM 的事件操作 分为: 监听 触发        都定义在 EventTarget 接口____

所有节点对象都部署了 EventTarget 接口,其他一些需要事件通信的浏览器内置对象(比如,XMLHttpRequest、AudioNode、AudioContext)也部署了这个接口。

.addEventListener();        绑定事件的监听函数

.removeEventListener();        移除事件的监听函数

.dispatchEvent();        触发事件

  • EventTarget.addEventListener(eventType, listener[, useCapture]);

用于在当前节点或对象上,定义一个特定事件的监听函数。

一旦这个事件发生,就会执行监听函数。

可以为针对当前对象的同一个事件,添加多个不同的监听函数。这些函数按照添加顺序触发,即先添加先触发。

如果为同一个事件多次添加同一个监听函数,该函数只会执行一次,多余的添加将自动被去除(不必使用removeEventListener方法手动去除)。

  • 该方法没有返回值
  • 参数:

eventType        事件名称,大小写敏感。

listener        监听函数。事件发生时,会调用该监听函数。

  • 注意:
  • 除了监听函数,还可以是一个 具有 handleEvent 方法的对象
  • btn.addEventListener(‘click‘,   {
                                        handleEvent: function (event) {
                                            console.log(‘click‘);
                                        }
                                    }, false);

[useCapture]        是否在捕获阶段(capture)触发(参见后文《事件的传播》部分)默认为 false(监听函数只在冒泡阶段被触发)。该参数可选

  • 注意:
  • 除了布尔值 useCapture,还可以是一个属性配置对象
  • 该对象有以下属性:

capture: 布尔值,表示该事件是否在捕获阶段触发监听函数。

once: 布尔值,表示监听函数是否只触发一次,然后就自动移除。

passive: 布尔值,表示监听函数不会调用事件的 preventDefault 方法。默认为 true 如果监听函数调用了,浏览器将忽略这个要求,并在监控台输出一行错误。

  • 希望事件监听函数只执行一次,可以打开属性配置对象的once属性
  • ele.addEventListener(‘click‘, function (event) {
      // 只执行一次的代码
    }, {once: true});
  • 如果希望向监听函数传递参数,可以用匿名函数包装一下监听函数
  • var box = document.getElementById(‘div1‘);
    box.addEventListener(‘click‘, function () {
        myPrint(‘Hello‘);
    }, false);
    
    function myPrint(x) {
        console.log(x);
    }
  • EventTarget.removeEventListener(eventType, listener);

用来移除 .addEventListener() 方法添加的事件监听函数。

该方法没有返回值

listener 在绑定时是 匿名函数,那么将无法直接用 .removeEventListener() 移除。

  • EventTarget.dispatchEvent(Event对象的实例)

在当前节点上触发指定事件,从而触发监听函数的执行。

  • 返回一个布尔值

只要有一个监听函数调用了 Event.preventDefault(),则返回值为 false,否则为 true

  • ele.addEventListener(‘click‘, hello, false);
    
    var event = new Event(‘click‘);
    ele.dispatchEvent(event);    // 主动触发 click 事件

2. 浏览器的事件模型

就是通过监听函数(listener)对事件做出反应。

事件发生后,浏览器监听到了这个事件,就会执行对应的监听函数。

____这是事件驱动编程模式(event-driven)的主要编程方式

  • 绑定事件监听函数的三种方法:

在 html 标签 中直接绑定

  • 只会在冒泡阶段触发
  • 缺点: 违反了 HTML 与 JavaScript 代码相分离的原则
  • <body onload="doSomething()">    <!-- 等同于 document.body.setAttribute("onload", "doSomething()"); -->
    <div id="box" onclick="console.log(‘触发事件‘)">    // this 输出 box

在 js 代码中,给元素对象 的事件属性绑定监听函数

  • 众所周知的 DOM0 级事件模型 绑定方式,也只会在冒泡阶段触发
  • 缺点: 同一个事件只能定义一个监听函数,也就是说,如果定义两次onclick属性,后一次定义会覆盖前一次
  • window.onload = doSomething;
    
    div.onclick = function (event) {
        console.log(‘触发事件‘);
    };

使用 EventTarget.addEventListener() 绑定

  • 众所周知的 DOM2 级事件模型 绑定方式
  • window.addEventListener(‘DOMContentLoaded‘, doSomething, false);
  • 优点:

除了 DOM 节点,其他对象(比如window、XMLHttpRequest等)也有这个接口,等于是整个 JavaScript 统一的监听函数接口

能够指定在哪个阶段(捕获阶段还是冒泡阶段)触发监听函数

同一个事件可以添加多个监听函数

3. 事件的传播

使得同一个事件会在多个节点上触发

  • 分成三个阶段

“捕获阶段”(capture phase)        从 window 对象 传导到 目标节点
“目标阶段”(target phase)        在目标节点上触发
“冒泡阶段”(bubbling phase)        从 目标节点 传导回 window对象

  • var phases = {
        1: ‘capture‘,
        2: ‘target‘,
        3: ‘bubble‘
    };
    
    var div = document.querySelector(‘div‘);
    var p = document.querySelector(‘p‘);
    
    div.addEventListener(‘click‘, callback, true);
    div.addEventListener(‘click‘, callback, false);
    
    p.addEventListener(‘click‘, callback, true);
    p.addEventListener(‘click‘, callback, false);
    
    function callback(event) {
        console.log("Tag: " + event.currentTarget.tagName,
                    "EventPhase: " + phases[event.eventPhase]);
    };
    
    // 点击以后的结果
    // Tag: ‘DIV‘.
    // EventPhase: ‘capture‘
    
    // Tag: ‘P‘
    // EventPhase: ‘target‘
    
    // Tag: ‘P‘
    // EventPhase: ‘target‘
    
    // Tag: ‘DIV‘
    //EventPhase: ‘bubble‘
  • 注意:

浏览器总是假定 click 事件的目标节点,就是点击位置嵌套最深的那个节点

事件传播的最上层对象是window,接着依次是document,html(document.documentElement)和body(document.body)

也就是说,上例的事件传播顺序,

在捕获阶段依次为window、document、html、body、div、p

在冒泡阶段依次为p、div、body、html、document、window。

  • 事件委派 / 事件代理(delegation)

把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件

  • 优点:

只要定义一个监听函数,就能处理多个子节点的事件,而不用在每个<li>节点上定义监听函数

而且以后再添加子节点,监听函数依然有效

  • 如果希望事件到某个节点为止,不再传播,可以使用事件对象的 event.stopPropagation() 方法

但是,stopPropagation方法只会阻止事件的传播,

不会阻止该事件触发 <p> 节点的其他 click 事件的监听函数。

也就是说,不是彻底取消click事件

  • p.addEventListener(‘click‘, function (event) {
      event.stopPropagation();
      console.log(1);    // 不会触发
    });
    
    p.addEventListener(‘click‘, function(event) {
      // 会触发
      console.log(2);
    });
  • 如果想要彻底取消该事件不再触发后面所有click的监听函数,可以使用 event.stopImmediatePropagation() 方法

4. Event 对象

Event 对象本身就是一个构造函数,可以用来生成新的实例

  • event = new Event(type, options);

接收两个参数:

  • type        字符串,表示 事件的名称
  • options        对象,表示 事件对象的配置。

该对象主要有下面两个属性

  • bubbles        布尔值,可选,默认为 false,表示事件对象是否冒泡

如果不是显式指定 bubbles 属性为 true,生成的事件就只能在 “捕获阶段” 触发监听函数

  • cancelable        布尔值,可选,默认为false,表示事件是否可以被取消

即能否用 event.preventDefault() 取消这个事件。

一旦事件被取消,就好像从来没有发生过,不会触发浏览器对该事件的默认行为

  • 实例属性

Event.bubbles

表示当前事件是否会冒泡。

返回一个布尔值,除非显式声明,Event构造函数生成的事件,默认是不冒泡的。

该属性为只读属性,用来判断 Event 实例是否可以冒泡

Event.eventPhase

表示事件目前所处的阶段。

返回一个整数常量,该属性只读

  • 0,事件目前没有发生。
    1,事件目前处于捕获阶段,即处于从祖先节点向目标节点的传播过程中。
    2,事件到达目标节点,即 Event.target 属性指向的那个节点。
    3,事件处于冒泡阶段,即处于从目标节点向祖先节点的反向传播过程中。

Event.cancelable

表示事件是否可以取消。

返回一个布尔值,该属性为只读属性,

一般用来判断 Event 实例是否可以被取消

  • 当 Event.cancelable 属性为true 时,调用 Event.preventDefault(); 就可以取消这个事件,阻止浏览器对该事件的默认行为。
  • 如果事件不能取消,调用 Event.preventDefault() 会没有任何效果。
  • 所以使用这个方法之前,最好用 Event.cancelable 属性 判断一下是否可以取消
  • /**** 封装 禁止浏览器默认行为 ****/function preventEvent(event) {
        if (event.cancelable) {
            event.preventDefault();
        } else {
            console.warn(‘This event couldn\‘t be canceled.‘);
            console.dir(event);
        }
    }

Event.cancelBubble

阻止事件的传播。        如果设为true,相当于执行Event.stopPropagation()

是一个布尔值

Event.defaultPrevented

表示该事件是否调用过 Event.preventDefault() 方法。

返回一个布尔值,该属性只读。

Event.currentTarget

返回 事件当前所在的节点,即正在执行的监听函数所绑定的那个节点,随事件传播过程而变化

Event.target

返回 原始触发事件的那个节点,即事件最初发生的节点,事件传播过程中是固定不变的

Event.type

表示事件类型。

返回一个字符串,事件的类型是在生成事件的时候。

该属性只读

Event.timeStamp

返回一个毫秒时间戳,表示事件发生的时间。

它是相对于网页加载成功开始计算的。

  • 实例计算鼠标移动速度,每秒移动的 px 值
  • var previousX;
    var previousY;
    var previousT;
    
    window.addEventListener(‘mousemove‘, function(event) {
        if (previousX !== undefined &&
            previousY !== undefined &&
            previousT !== undefined ){
            var deltaX = event.screenX - previousX;    // 获取  当前的 xOffset
            var deltaY = event.screenY - previousY;    // 获取  当前的 yOffset
            var deltaD = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
    
            var deltaT = event.timeStamp - previousT;
            console.log(deltaD / deltaT * 1000);    // 速度 = 路程 / 时间
        };
    
        previousX = event.screenX;    // 获取移动前的 x
        previousY = event.screenY;    // 获取移动前的 y
        previousT = event.timeStamp;    // 获取当前时间戳
    });

Event.isTrusted

表示该事件是否由真实的用户行为产生。

返回一个布尔值

比如,用户点击链接会产生一个 click 事件,该事件是用户产生的;Event 构造函数生成的事件,则是脚本产生的。

Event.detail

该属性返回一个数值,表示事件的某种信息。

只有浏览器的 UI (用户界面)事件才具有此属性。

具体含义与事件类型相关。

比如,

对于 click 和 dbclick 事件,Event.detail 是鼠标按下的次数(1表示单击,2表示双击,3表示三击);

对于鼠标滚轮事件,Event.detail 是滚轮正向滚动的距离,负值就是负向滚动的距离,返回值总是 3 的倍数。

  • 实例方法

Event.preventDefault()

取消浏览器对当前事件的默认行为。

比如点击链接后,浏览器默认会跳转到另一个页面,使用这个方法以后,就不会跳转了;

再比如,按一下空格键,页面向下滚动一段距离,使用这个方法以后也不会滚动了。

再比如,浏览器的默认行为是单击会选中单选框,取消这个行为,就导致无法选中单选框

该方法生效的前提是,事件对象的 cancelable 属性为true,如果为 false,调用该方法没有任何效果

注意,该方法只是取消事件对当前元素的默认影响,不会阻止事件的传播。

如果要阻止传播,可以使用 event.stopPropagation() 或 event.stopImmediatePropagation() 方法

  • 实例: 为文本输入框设置校验条件。如果用户的输入不符合条件,就无法将字符输入文本框。
  • // HTML 代码为
    // <input type="text" id="my-input" />
    var input = document.getElementById(‘my-input‘);
    input.addEventListener(‘keypress‘, checkName, false);
    
    function checkName(e) {
        if (e.charCode < 97 || e.charCode > 122) {
            e.preventDefault();
        }
    }

    上面代码为文本框的 keypress 事件设定监听函数后,将只能输入小写字母,否则输入事件的默认行为(写入文本框)将被取消,导致不能向文本框输入内容

Event.stopPropagation()

阻止事件在 DOM 中继续传播,防止再触发定义在别的节点上的监听函数,

但是不包括在当前节点上其他的事件监听函数

Event.stopImmediatePropagation()

阻止同一个事件的所有监听函数被调用,不管监听函数定义在当前节点还是其他节点。

也就是说,该方法阻止事件的传播,比Event.stopPropagation()更彻底

Event.composedPath()

返回一个节点数组,成员是事件的最底层节点依次冒泡经过的所有上层节点

原文地址:https://www.cnblogs.com/tianxiaxuange/p/10099101.html

时间: 2024-10-07 15:34:17

(92)Wangdao.com_第二十五天_事件 Event的相关文章

经典算法题每日演练——第二十五题 块状链表

原文:经典算法题每日演练--第二十五题 块状链表 在数据结构的世界里,我们会认识各种各样的数据结构,每一种数据结构都能解决相应领域的问题,每一种数据结构都像 是降龙十八掌中的某一掌,掌掌毙命... 当然每个数据结构,有他的优点,必然就有它的缺点,那么如何创造一种数据结构 来将某两种数据结构进行扬长避短,那就非常完美了.这样的数据结构也有很多,比如:双端队列,还有就是今天讲的 块状链表, 我们都知道 数组 具有 O(1)的查询时间,O(N)的删除,O(N)的插入... 链表 具有 O(N)的查询时

centos lamp/lnmp阶段复习 第二十五节课

centos  lamp/lnmp阶段复习   第二十五节课 上半节课 下半节课 f

第二十五天 慵懒的投射在JDBC上的暖阳 —Hibernate的使用(四)

6月4日,晴天."晴日暖风生麦气,绿阴幽草胜花时."      "道"是只有中国人才懂得并孜孜以求的特殊的宇宙存在感的体验.全世界只有中文才能阐释"道"的全部涵义.然而所谓阐释,并不重在定义,更多的还是感受. "道"既在"虚无"之内,又超越了"虚无",成为中国文化最平常但又最玄妙的一种境界. 老庄认为:道是宇宙的本体,即是宇宙万物的老祖宗.    老外认为:Tao is the sour

第二十五课:超越抽象极限

1.一个阶跃输入,后面接戴维南电阻,测量点Vout,之后接其他设计电路,末端开路 理论上在同一时刻Vout也发生阶跃(例如 0到5V) 实际上,在t=0是,输出上升到一半,持续一段时间才会继续上升到5V 这是因为当导线非常长时,需要考虑信号传输时间 脉冲到达末端返回到Vo,Vo得到一个回波,两个2.5V相加就达到5V 这个阻抗对于多数导线都等于50欧姆,称之为特性阻抗 解决方法:换短的导线: 改变时钟信号 2.同一个电压对多个反相器供电 前一个反相器在上端导通时,通过的电流变化会在电感上产生压降

NeHe OpenGL教程 第二十五课:变形

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第二十五课:变形 变形和从文件中加载3D物体: 在这一课中,你将学会如何从文件加载3D模型,并且平滑的从一个模型变换为另一个模型. 欢迎来到这激动人心的一课,在这一课里,我们将介绍模型的变形.需要注意的是各个模型必须要有相同的顶点,

Gradle 1.12用户指南翻译——第二十五章. Scala 插件

其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://github.com/msdx/gradledoc/tree/1.12. 直接浏览双语版的文档请访问: http://gradledoc.qiniudn.com/1.12/userguide/userguide.html. 另外,Android 手机用户可通过我写的一个程序浏览文档,带缓存功能的,目前

centos NFS/FTP服务配置 第二十五节课

centos  NFS/FTP服务配置   第二十五节课 上半节课 下半节课 f

Training的第二十五天

今天学到了新的知识就是:转义字符,了解了类型转换的规则和自动转换发生的条件.学会了数据类型的强制转换. Training的第二十五天

javaSE第二十五天

第二十五天????399 1:如何让Netbeans的东西Eclipse能访问.????399 2:GUI(了解)????399 (1)用户图形界面????399 (2)两个包:????399 (3)主要方法:????399 A:javax.swing包下的方法????399 B:监听机制的应用????400 (4)GUI的继承体系????400 (5)事件监听机制(理解)????401 (6)适配器模式(理解)????401 案例解释????401 1. UserDao(顶层接口)????40