JavaScript常见事件处理程序实例总结


Posted in Javascript onJanuary 05, 2019

本文实例总结了JavaScript常见事件处理程序。分享给大家供大家参考,具体如下:

事件指的是使用者或者浏览器自身执行的某种动作(比如点击事件)。响应这些事件的函数就叫做事件处理程序(或者叫事件监听器)。事件处理程序的名字以“on”为前缀,比如 click 事件的事件处理程序就是 onclick。

1 HTML 事件处理程序

如果某个元素支持某个事件,那么它都有一个与相应的事件处理程序同名的 HTML 属性,我们可以通过这个属性来指定 JS:

<input type="button" value="点我" onclick="alert('点击过咯')"/>

因为这里的脚本是嵌入在 HTML 元素的属性中,所以使用了单引号!

也可以调用在页面的其他地方定义的脚本:

<input type="button" value="Click me" onclick="showMessage()">
<script type="text/javascript">
  function showMessage() {
    console.log("Hello World!");
  }
</script>

事件处理程序的代码在执行时,可以访问到全局作用域中的任何代码!

这样指定的事件处理程序,会创建一个封装着元素属性值的函数,它有一个局部变量 event,就是事件对象:

<input type="button" value="点我" onclick="alert(event.type)"/>

通过 event 变量,可以直接访问事件对象。在这个函数内部,this 值等于事件的目标元素:

<input type="button" value="点我" onclick="alert(this.value)"/>

可以通过这个动态创建的函数,来扩展它的作用域。在这个函数内部,可以访问 document 以及该元素本身的成员,这个函数是像这样使用 with 来扩展作用域的:

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

所以,在事件处理程序中,要访问自己的属性就变得很容易啦 O(∩_∩)O~:

<!-- 输出 “点我” -->
<input type="button" value="点我" onclick="alert(value)"/>

如果当前元素是一个表单输入元素,则作用域中还会包含访问表单元素(父元素)的入口,所以这个函数应该是这样的:

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

这样事件处理程序就无需引用表单元素,就可以直接访问到表单中的其他字段啦O(∩_∩)O~:

<form method="post">
  <input type="text" name="username" value="">
  <input type="button" value="Echo Usernmame" onclick="console.log(username.value);">
</form>

在 HTML 中直接指定事件处理程序会有这些缺点:

  • 时差问题——假设函数是定义在页面最底部,如果用户在页面还未解析到这个函数时,就点击了按钮,就会引发错误。所以很多 HTML 事件处理程序都会被封装在 try-catch 块中:
<input type="button" value="点我" onclick="try{alert(value);} catch(ex){}"/>
  • 扩展事件处理程序的作用域链,在不同的浏览器中结果可能会不同。
  • HTML 与 JavaScript 代码紧密耦合。要修改事件处理程序,就需要修改两个地方,所以很多开发人员转而使用 JavaScript 来指定事件处理程序。

2 DOM0 级事件处理程序

它是通过将一个函数赋值给事件处理程序的属性,来指定事件处理程序的。要使用这种方法,必须先取得一个要操作的对象的引用。

每个元素(包括 window 和 document) 都有自己的事件处理程序属性,它们通常是小写,比如 onclick。将属性的值设置为函数,就指定了事件处理程序。

DOM0 级事件处理程序是元素的方法,它是在元素的作用域内运行的,因此程序中的 this 引用的是当前元素:

<button id="myBtn">点我</button>
<script type="text/javascript">
  var btn = document.getElementById("myBtn");
  btn.onclick = function () {
    console.log(this.id);//myBtn
  }
</script>

可以通过 this 访问元素的任何属性和方法。DOM0 级事件处理程序会在事件流的冒泡阶段被处理。

也可以像这样删除这样指定的事件处理程序:

btn.onclick = null; //删除指定的事件处理程序

注意: 如果使用的是 HTML 指定的事件处理程序,那么 onclick 属性的值就是一个包含着在同名 HTML 特性中指定的代码函数。将相应的属性设置为 null,也可以删除以这种方式指定的事件处理程序。

3 DOM2 级事件处理程序

  • addEventListener():指定事件处理程序。
  • removeEventListener():删除事件处理程序。

所有的 DOM 节点都包含这两个方法。它们都接受 3 个参数:要处理的事件名、事件处理程序函数、布尔值。最后一个参数如果是 true,表示在捕获阶段调用事件处理程序;如果是 false,表示在冒泡阶段调用事件处理程序。

DOM2 级事件处理程序可以很方便地添加多个事件处理程序:

var btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
  console.log(this.id);
}, false);
btn.addEventListener("click", function () {
  console.log("Hello world!");
}, false);

这些事件处理程序会按照添加它们的顺序依序触发。

通过 addEventListener() 添加的事件处理程序只能使用 removeEventListener() 移除!移除时传入的参数必须与添加时的参数相同。这也就意味着通过 addEventListener() 添加的匿名函数将无法被移除:

var handler = function () {
  console.log("Hi deniro");
};
btn.addEventListener("click", handler, false);
btn.removeEventListener("click", handler, false);//移除成功

大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容浏览器。所以如果不是特别需要,请不要在事件捕获阶段注册事件处理程序。

注意: IE9、Firefox、Safari、Chrome 和 Opera 支持 DOM2 级事件处理程序。

4 IE 事件处理程序

IE 实现了与 DOM 类似的方法:attachEvent()detachEvent()。它们接受两个参数:事件处理程序名称和事件处理程序函数。因为 IE8 及早期版本只支持事件冒泡,所以使用 attachEvent() 添加的事件处理程序会被添加到冒泡阶段。

这样为按钮添加一个事件处理程序:

var btn = document.getElementById("myBtn");
  btn.attachEvent("onclick", function () {
});

IE 的 attachEvent() 与 DOM0 级方法的区别是事件处理程序的作用域不同。 DOM0 级方法中,事件处理程序会在其所属元素的作用域内运行;而使用 attachEvent() ,事件处理程序会在全局作用域中运行,所以 this 等于 window:

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function () {
  console.log("Clicked");
  console.log(this === window);//true;this 为全局作用域
});

也可以为一个元素添加多个事件处理程序:

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function () {
  console.log("Clicked");
  console.log(this === window);//true;this 为全局作用域
});
//IE10 中多个事件是按照事件定义的顺序执行
btn.attachEvent("onclick", function () {
  console.log("Hello world!");
});

IE8 及之前的版本,是以添加它们的相反顺序进行,IE9 修复了这个问题。

可以通过 detachEvent() 来移除添加的事件处理程序,但必须提供相同的参数。所以它也不能移除之前通过匿名函数添加的事件处理程序。只要能够将对相同函数的引用作为参数,就可以移除添加的事件处理程序咯:

<button id="myBtn">点我</button>
<script type="text/javascript">
  var btn = document.getElementById("myBtn");
  var handler = function () {
    console.log("Clicked");
  }
  btn.attachEvent("onclick", handler);
  btn.detachEvent("onclick", handler);
</script>

注意: IE 和 Opera 支持 IE 事件处理程序。

5 跨浏览器的事件处理程序

只要恰当地运用能力检测,就能写出跨浏览器的事件处理程序。

var EventUtil = {
  /**
   * 添加事件
   * @param element 要操作的元素
   * @param type 事件名称
   * @param handler 事件处理函数
   */
  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;
    }
  },
  /**
   * 移除事件
   * @param element 要操作的元素
   * @param type 事件名称
   * @param 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;
    }
  }
}

这样使用:

<button id="myBtn">点我</button>
<script type="text/javascript" src="EventUtil.js"/>
<script type="text/javascript">
  var btn = document.getElementById("myBtn");
  var handler = function () {
    console.log("Clicked");
  }
  EventUtil.addHandler(btn, "click", handler);
  EventUtil.removeHandler(btn, "click", handler);
</script>

还有一点,DOM0 级对每一个事件只支持一个事件处理程序,好在现在只支持 DOM0 级事件处理程序的浏览器几乎已经没有咯,所以不用担心啦 O(∩_∩)O~

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript针对DOM的应用实例(一)
Apr 15 Javascript
Lua表达式和控制结构学习笔记
Dec 15 Javascript
JavaScript中的cacheStorage使用详解
Jul 29 Javascript
简单讲解AngularJS的Routing路由的定义与使用
Mar 05 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
Aug 29 Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
Dec 23 Javascript
微信小程序实现基于三元运算验证手机号/姓名功能示例
Jan 19 Javascript
Vuex持久化插件(vuex-persistedstate)解决刷新数据消失的问题
Apr 16 Javascript
node.js中module模块的功能理解与用法实例分析
Feb 14 Javascript
vue实现瀑布流组件滑动加载更多
Mar 10 Javascript
详解node.js创建一个web服务器(Server)的详细步骤
Jan 15 Javascript
深入浅析React中diff算法
May 19 Javascript
JavaScript代码调试方法实例小结
Jan 05 #Javascript
JavaScript实现连连看连线算法
Jan 05 #Javascript
JavaScript错误处理操作实例详解
Jan 04 #Javascript
JSON基本语法及与JavaScript的异同实例分析
Jan 04 #Javascript
JavaScript解析及序列化JSON的方法实例分析
Jan 04 #Javascript
Node.js操作系统OS模块用法分析
Jan 04 #Javascript
Node.js console控制台简单用法分析
Jan 04 #Javascript
You might like
php FPDF类库应用实现代码
2009/03/20 PHP
PHP5多态性与动态绑定介绍
2015/04/03 PHP
通过event对象的fromElement属性解决热区设置主实体的一个bug
2008/12/22 Javascript
js 分页全选或反选标识实现代码
2011/08/09 Javascript
基于JQuery的Select选择框的华丽变身
2011/08/23 Javascript
ExtJS4 Grid改变单元格背景颜色及Column render学习
2013/02/06 Javascript
各种页面定时跳转(倒计时跳转)代码总结
2013/10/24 Javascript
javascript 操作符(~、&amp;、|、^、)使用案例
2014/12/31 Javascript
jquery通过load获取文件的内容并跳到锚点的方法
2015/01/29 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
javascript实现博客园页面右下角返回顶部按钮
2015/02/22 Javascript
jquery控制显示服务器生成的图片流
2015/08/04 Javascript
jquery密码强度校验
2015/12/02 Javascript
JS基于面向对象实现的拖拽功能示例
2016/12/20 Javascript
js循环map 获取所有的key和value的实现代码(json)
2018/05/09 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【凹多边形的分离轴检测算法】
2018/12/13 Javascript
Sublime Text3 配置 NodeJs 环境的方法
2020/05/20 NodeJs
[01:03:13]VG vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python教程之用py2exe将PY文件转成EXE文件
2014/06/12 Python
简单谈谈python中的Queue与多进程
2016/08/25 Python
python中is与双等于号“==”的区别示例详解
2017/11/21 Python
Python基于socket实现简单的即时通讯功能示例
2018/01/16 Python
Python数据处理numpy.median的实例讲解
2018/04/02 Python
python保存数据到本地文件的方法
2018/06/23 Python
Django中的文件的上传的几种方式
2018/07/23 Python
pycharm配置git(图文教程)
2019/08/16 Python
英国护肤品购物网站:Beauty Expert
2016/08/19 全球购物
运动会100米解说词
2014/01/23 职场文书
大学生村官考核材料
2014/05/23 职场文书
汽车销售经理岗位职责
2014/06/09 职场文书
2014年体育教师工作总结
2014/12/03 职场文书
2015年个人招商工作总结
2015/04/25 职场文书
2015年远程教育工作总结
2015/05/20 职场文书
大学毕业典礼致辞
2015/07/29 职场文书
pytorch中的model=model.to(device)使用说明
2021/05/24 Python
vue实力踩坑之push当前页无效
2022/04/10 Vue.js