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

Posted tianxiaxuange

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(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()

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

 

以上是关于(92)Wangdao.com_第二十五天_事件 Event的主要内容,如果未能解决你的问题,请参考以下文章

(95)Wangdao.com_第二十八天_进度事件

(89)Wangdao.com第二十二天_JavaScript DocumentFragment 节点

javaSE第二十五天

(82)Wangdao.com第十六天1017__ JavaScript 异步操作

(86)Wangdao.com第十九天_JavaScript

团队冲刺第二十五天