事件处理程序

事件处理程序即响应某个事件的函数

事件处理程序以 “on” 开头

如“onclick”,“onload”

HTML事件处理程序

某个元素支持的每种事件都可以使用一个与响应的事件处理程序同名的HTML特性来指定

这个特性的值应该是能够执行的script代码

如:

<input type="button" value="click me" onclick="alert('clicked')"/>

此外也可以直接调用在文档其它部分定义的函数作为事件处理程序所执行的代码

如:

<input type="button" value="click me" onclick="functionClick()"/>

以这样的方式指定事件处理程序会创建一个封装着元素属性值的函数

该函数有一个局部变量 event (事件对象),通过event变量可以访问事件对象

并且在这个函数内部,this指向事件的目标元素

此外,这个动态创建的函数内部可以像访问局部变量一样访问document以及该元素本身的成员

这是因为HTML指定的事件处理函数会像下面这样拓展函数作用域

function(){
with(document){
with(this){
//元素属性值
}
}
}

这样的目的无非是为了让事件处理程序无需引用表单元素就能访问其它表单字段

但是这种方式有以下缺点:

  1. 存在时差问题,即触发事件时事件处理程序可能并不具备执行条件
  2. 这样拓展的事件处理程序作用域链在不同的浏览器可能会导致不同的结果
  3. HTML与JS代码的紧密耦合,使代码的维护成本增加

DOM0级事件处理程序

通过JS指定事件处理程序的传统方式是在第四代web浏览器出现的,只需要将一个函数赋值给事件处理程序属性即可

这种方式一直沿用至今,因为这种方法非常简单并且具备跨浏览器优势

如下所示:

var btn = document.getElementByTagName("button")[0];
btn.onclick = function(){
alert("clicked");
}

使用DOM0级方法指定的事件处理程序被认为是元素方法

因为事件处理程序运行在元素作用域中,所以this引用当前元素

以这种方式定义的事件处理程序会在事件流的冒泡阶段被处理

如果需要删除事件处理程序,只需要将事件处理程序属性的值设为 null 即可

btn.onclick = null;

DOM2级事件处理程序

“DOM级事件”定义了两个方法用于指定和删除事件处理程序

  1. addEventListener()指定事件处理函数
  2. removeEventListener()移除事件处理函数

上面两个方法都接收三个参数

  1. 要处理的事件名
  2. 作为事件处理程序的函数
  3. 布尔值 true 表示在捕获阶段调用事件处理程序  false在冒泡阶段调用事件处理程序

与DOM0级一样DOM2级也是在元素作用域中执行

与DOM0最大的区别在于,DOM2级可以为一个元素添同一事件加多个事件处理程序,而DOM0级重复设置后面的事件处理程序将会覆盖前面的事件处理程序

DOM2级同一元素的同一事件的事件处理程序被事件触发时会按照添加顺序执行

由 addEventListener()添加的事件只能由 removeEventListener()移除

这也意味着,如果addEventListener添加了匿名函数作为事件处理程序将无法被移除

PS.一般来说为了最大限度地保证浏览器兼容,会把事件注册在事件冒泡阶段

IE事件处理程序

IE实现了与DOM中类似地两个方法:

  1. attachEvent()
  2. detachEvent()

这两个方法接收相同的两个参数

  1. 事件名称
  2. 事件处理程序函数

由于低版本IE只支持冒泡,所以这两个方法会将事件处理程序添加到冒泡阶段

这里要注意的是:

  1. 事件名称与DOM不一致列如click事件 addEventListener 使用 “click” 而 attachEvent使用“onclick”
  2. 作用域不同,attachEvent事件添加的函数作用域为全局作用域,所以this等于 window
  3. 多个事件执行顺序不同 与DOM2级相反即与添加事件的顺序相反

跨浏览器事件处理程序

为了隔离浏览器差异,我们可能会使用一些JS库来完成跨浏览器的事件处理程序的兼容

当然我们也可以自己实现

大体实现如下:

// 跨平台事件绑定 参数 1.目标元素 2.目标事件 3.事件处理函数
function addEvent(ele,eve,fun) {
if(ele.addEventListener){
ele.addEventListener(eve,fun,false);
}else if(ele.attachEvent){
ele.attachEvent.call(ele,"on"+eve,fun,false);
}else{
ele["on"+eve] = fun;
}
}
// 跨平台事件移除
function removeEvent(ele,eve,fun) {
if(ele.removeEventListener){
ele.removeEventListener(eve,fun,false);
}else if(ele.detachEvent){
ele.detachEvent.call(ele,"on"+eve,fun,false);
}else{
ele["on"+eve] = null;
}
}

Javascript高级编程学习笔记(58)—— 事件(2)事件处理程序的更多相关文章

  1. Javascript高级编程学习笔记(57)—— 事件(1)事件流

    事件 JS与HTML的交互是通过事件实现的 而事件指的就是:文档或浏览器窗口特定的交互瞬间 可以通过侦听器来预定事件,以便在事件发生时执行相应的代码 这种模式也是设计模式中的观察者模式 事件流 有了事 ...

  2. Javascript高级编程学习笔记(70)—— 事件(14)内存和性能

    由于事件处理程序是现代的web程序交互能力的提供者 所以在日常实践中,我们免不了要向页面中添加大量的事件处理程序(不管是用于用户交互还是用于统计用户数据) 在创建GUI(图形用户界面)的语言(如C#) ...

  3. Javascript高级编程学习笔记(69)—— 事件(13)触摸与手势事件

    触摸与手势事件 由于移动设备既没有鼠标也没有键盘,所以在为移动浏览器开发交互性网页时,常规的鼠标键盘事件根本不够用 所以早期的苹果为Safari 添加了一些与触摸相关的事件 随着后面Android的W ...

  4. Javascript高级编程学习笔记(67)—— 事件(11)HTML5事件

    DOM规范没有涵盖所有浏览器支持的所有事件 而许多浏览器出于满足用户需求,或解决特殊问题的目的,实现了一些自定义事件 HTML5列出了浏览器应该支持的所有事件,这里只讨论得到浏览器完善支持的事件(并非 ...

  5. Javascript高级编程学习笔记(66)—— 事件(10)变动事件

    变动事件 DOM2级的变动事件,能在DOM中的一部分发生变化时给出提示 变动事件是为XML或HTML DOM 设计的,并不特定于某种语言 DOM2级定义了如下变动事件: DOMSubtreeModif ...

  6. Javascript高级编程学习笔记(63)—— 事件(7)鼠标及滚轮事件

    鼠标与滚轮事件 鼠标事件是web开发中最常用的一类事件,毕竟鼠标是最主要的定位设备 DOM3级事件中定义了9个鼠标事件: click:在用户单击主鼠标按钮(一般为鼠标左键)或者按下回车时触发,这一点对 ...

  7. Javascript高级编程学习笔记(62)—— 事件(6)焦点事件

    焦点事件 焦点事件会在页面元素获得或者失去焦点时触发,利用焦点事件和 document.hasFocus() 方法配合使用 以及 document.activeElement 属性配合可以知晓用户在页 ...

  8. Javascript高级编程学习笔记(61)—— 事件(5)UI事件

    UI事件 UI事件是指那些不一定与用户操作有关的事件 这些事件在DOM规范出现之前,都是以各种不同的形式存在于不同的浏览器 而在DOM事件中为了保证向后兼容,现有的UI事件如下: DOMActivat ...

  9. Javascript高级编程学习笔记(59)—— 事件(3)事件对象

    事件对象 在触发DOM‘事件时,会产生一个事件对象 event 该对象包含着所有与事件有关的信息 所有浏览器都支持 event 对象但是支持的方式有所不同 DOM事件对象 兼容DOM的浏览器会将eve ...

  10. Javascript高级编程学习笔记(68)—— 事件(12)设备事件

    设备事件 随着智能手机与平板电脑的普及,为了更好地让用户与这些设备进行交互 浏览器引入了一种新的方式,而一类新的事件也应运而生,这就是设备事件 W3C从2011年开始制定关于设备事件的草案 下面将会介 ...

随机推荐

  1. .Net圈子里的一些看法

    金三银四招聘季,不一定一定要跳巢,但是出去看看行情还是有必要的,所以就有这篇随笔. 首先,这里说的.Net圈子是只两个方面 第一,技术人才,属于人的圈子 第二,技术本身,技术的圈子,也就是技术所涵盖的 ...

  2. Maven Nexus仓库地址

    收集的仓库地址如下: http://maven.wso2.org/nexus/content/groups/public/ http://jcenter.bintray.com/ http://mav ...

  3. 盯着这where or 终于出了点感觉

    AND 和 OR 运算符 AND 和 OR 可在 WHERE 子语句中把两个或多个条件结合起来. 如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录. 如果第一个条件和第二个条件中只要有 ...

  4. java去除数组重复元素的方法

    转载自:https://blog.csdn.net/Solar24/article/details/78672500 import java.util.ArrayList; import java.u ...

  5. Codeforces 1086D Rock-Paper-Scissors Champion

    Description \(N\) 个人排成一排, 每个人都事先决定出剪刀.石头.布. 每次可以任意选两个相邻的人进行决斗. 规则和游戏一样. 但是如果平局, 则掷硬币来决定胜负. 输的人下场. 现要 ...

  6. Java 字符编码(二)Java 中的编解码

    Java 字符编码(二)Java 中的编解码 java.nio.charset 包中提供了一套处理字符编码的工具类,主要有 Charset.CharsetDecoder.CharsetEncoder. ...

  7. cmd下的一些小技巧

    切换盘符:[盘符]+: tips1: 在盘符A执行一条命令后的同时切换到盘符B:A:\>dir && B:(此处只能用&&或者&) tips2: 在盘符A ...

  8. AX_CreateAndPostSales

    static void CreateAndPostSales(Args _args) { List il = new List(Types::Record); SalesTable localSale ...

  9. WebApi 增加身份验证 (OAuth 2.0方式)

    1,在Webapi项目下添加如下引用: Microsoft.AspNet.WebApi.Owin Owin Microsoft.Owin.Host.SystemWeb Microsoft.Owin.S ...

  10. 得到一个文件夹中所有文件的名称的几个方法(命令指示符, C++, python)

    因为最近一直需要获得一个文件下的所有图片的名称,自己又总是跨平台使用,所以把自己在不同环境之下使用的方法总结如下 1.cmd 模式下 优点:简单 例如,我想将一个文件夹下的所有".jpg&q ...