事件

作者: Kennydaidai | 来源:发表于2017-09-20 18:06 被阅读56次

前言

前段时间在周会上被迫分享了一些 JavaScript 基础知识,后来听小伙伴反馈,组织性和逻辑性太乱,今天自己特意翻了下书本(JavaScript高级程序设计),以下是阅读后的整理,以便后续温故知新。

嗯,今天的主角是事件

事件

定义

以我的理解,事件就是指一系列的动作,像我们经常接触的click、dbclick以及键盘的keydown、keyup或者还有一些文档(DOM)的加载、图片的加载,焦点事件等等。其实事件的主要目的就是为了JavaScriptHTML更好的交互。

课本上的定义是:

事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间

事件流

事件流是事件中一个重要的概念,由于历史(IE与Netscape巴拉巴拉~)的原因,出现了两种完全相反的事件流概念。

首先看下事件流的定义:

事件流是描述页面接收事件的顺序

顾名思义,事件流就是指事件的流向嘛,这个很好理解。前面说两位爸爸提出了两个截然相反事件流概念,是啥呢?我想大家都应该有听过 事件捕获和事件冒泡

事件捕获

直接上图:


image.png

举个例子

<html>
  <body>
    <div>今晚该点我了,小哥!</div>
  </body>
</html>

单击div元素,click将会以以下顺序发生:

  1. document
  2. html
  3. body
  4. div

注意:
1.IE9一下不支持事件捕获;
2.DOM2级规范要求事件从document对象开始传播,但浏览器多数都是从window对象开始传播

事件冒泡

首先,说个重点因为浏览器兼容性问题,早期(IE9之前)是不支持事件捕获的,所以建议使用时间冒泡处理事件

上图


image.png

同样的代码(时间捕获的代码)

事件的顺序刚好相反:

  1. div
  2. body
  3. html
  4. document
DOM事件流

DOM2级事件 规定事件流包括3个阶段

  1. 事件捕获阶段
  2. 目标阶段
  3. 时间冒泡阶段

在DOM事件流中,实际的目标(div)在捕获阶段是不会接收到事件的,这意味着事件从documen->html->body就停止了。在事件处理中,将"处于目标阶段"看做是冒泡阶段的一部分。

但是,多数支持DOM2事件流的现代浏览器都实现了在捕获阶段触发事件对象上的事件,so~

以上是书本原话,大家自行体会。

注意,IE9以下是不支持DOM2级事件流的

事件处理程序

用来响应某个事件的函数叫做事件处理程序(或事件侦听器

为事件指定处理程序的方式有以下几种:

  1. HTML事件处理程序
  2. DOM0级时间处理程序
  3. DOM2级事件处理程序
  4. IE事件处理程序
HTML 事件处理程序

看代码

  • 方法一
<input type='button' value='Click me' onclick='alert(123)' />
  • 方法二
<script>
  function showMessage(){
    console.log(123);
  }
</script>
<input type='button' value='Click me' onclick='showMessage()' />

这两种注册事件的方式,大家应该都不陌生,需要一提的是在方法一中,代码部分(alert(123))是作为JavaScript代码来处理的且是嵌套在html代码中的,如果代码中包含未经过转义的HTMl语法字符是有问题的,所以请转义OR用第二种方法。

代码执行时的作用域问题
  • 在代码执行时以上两种方法都有权访问全局作用域中的任何代码
  • 当前的this指向目标元素

作用域扩展
看实例代码:JSFiddeler代码示例

代码截图


作用域扩展.png
  • 在函数内部,你可以像访问局部变量一样访问document及该元素本身的成员
  • 如果当前元素是一个表单的输入元素,则作用域中还会包含访问表单元素(父元素)的入口,这样可以更快的访问表单字段。
HTML事件处理程序的缺点
  • 时差问题,当事件触发时,事件处理程序可能尚不具备执行条件
    举个例子,前面的showMessage如果在按钮的下方,用户点击按钮时,showMessage还未加载完毕就会出现错误
  • 作用域链可能因为浏览器的的不同产生差异
  • HTML代码和JavaScript代码紧密耦合
DOM0 级时间处理程序

先说优点

  1. 简单
  2. 兼容性非常好,具有跨浏览器的优势

看看如何注册

var btn = document.getElementById('mybtn');
btn.onclick = function(){
  console.log('clicked');
}

嗯,简单不需要多说什么。

几点需要注意的

  • 处理程序中this指向当前元素
  • 该种方式添加的事件处理程序都是在事件流的冒泡阶段被处理的
  • btn.onclick=null时,可以去除事件绑定(有好处,日后展开)
DOM2 级处理程序

DOM2级事件定义了两个方法,用来处理和删除事件处理程序addEventListener()removeEventListener();所有实现DOM2级规范的dom节点都包含这两个方法;这两个函数有三个参数,依次顺序分别是:要处理的事件名称(click,load)、处理函数、以及一个布尔值。最后这个布尔值如果是true表示在捕获阶段调用时间处理程序,否则在冒泡阶段调用。

看代码

var btn = document.getElementById('mybtn');
btn.addEventListener('click',function(){
  console.log(1111);
},true);

如果需要将事件处理程序移除,必须使用有签名的处理函数,上述代码的匿名函数则无法移除`

btn.removeEventListener("click",handler,true)

优点

  • 可以添加多个处理程序
  • 解耦

福利:查看代码 ,可以稍稍理解下这里的捕获阶段调用事件处理程序和冒泡阶段调用是啥意思

IE处理程序

说实话,我个人是不太想说这个的,因为它会让人混乱,我建议还是先了解标准之后再来阅读这个比较好。但为了知识的连贯性,我还是大概说一下下。

IE早期的版本(我试了ie11好像已经去除了,估计还是ie9之前,具体没有找到资料)中实现了类似DOM2中的两个方法attachEventdetachEvent

以下列举这两个方法的不同

  • 因为IE8及更早的版本只支持时间冒泡,so 通过该方法注册的事件处理程序都会被添加到冒泡阶段
  • 看下代码
      btn.attachEvent('onclick',handler)
    
    多了个 on
  • this指向window
  • 注册了的多个处理程序的执行顺序和DOM2顺序相反,DOM2是先注册的先执行

跨浏览器的事件处理程序

var EventUtil = {
  addHandler : function(element, type, handler){
    if(element.addEventListener){
      element.addEventListener(type,handler,false);
    }else if(element.attachEvent){
      element.attachEvent('on' + type, handler)
    }else{
      element['on' + type] = handler;
    }
  },
  removeHandler : function(element,type,handler){
    if(element.removeEventListener){
      element.removeEventListener(type,handler,false);
    }else if(element.detachEvent){
      element.detachEvent('on'+type,handler);
    }else{
      element['on' + type] = null;
    }
  }
}

相关文章

  • JavaScript事件01——事件流

    大纲:概念(事件、事件流)事件流模型(事件冒泡、事件捕获、DOM事件流) 一、概念: 1、事件:事件就是用户或浏览...

  • 事件对象,事件监听,事件冒泡,事件代理

    一、事件对象 二、冒泡事件:(事件从子元素往父级元素向上触发事件)处理兼容问题:主流浏览器:e.stopPropa...

  • 事件总结

    DOM事件主要内容 事件流 事件注册 事件对象 事件分类 事件代理 什么是DOM事件? 事件是某个行为或者触发,比...

  • Javascript事件系统

    本文内容 事件基础 事件监听方式 事件默认行为 事件冒泡与事件捕获 事件绑定与事件委托 事件基础 注意:本文不会深...

  • Javascript事件-事件冒泡,事件捕获,事件监听和事件委托

    事件处理机制 (一)DOM事件流 DOM模型是一个树形结构,在DOM模型中,HTML元素是有层次的。当一个HTML...

  • 【事件】事件流

    1、JavaScript和HTML之间的交互通过事件实现的。2、事件流描述的是从页面中接收事件的顺序。3、IE 和...

  • 【事件】事件对象

    触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的额信息。(包括导致事件的元...

  • 【事件】事件类型

    DOM3 级事件规定了以下几类事件: UI(User Interface,用户界面)事件,当用户与页面上的元素交互...

  • 2018-09-10JQuery高级应用

    JQuery事件 window事件 鼠标事件 键盘事件 表单事件 事件注册语法$(对象).type(fn)type...

  • JS事件

    ?事件的相关术语 事件类型: 鼠标事件、键盘事件事件名称: click、dbclick等事件目标: 表示与发生事件...

网友评论

      本文标题:事件

      本文链接:https://www.haomeiwen.com/subject/oulosxtx.html