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 相关文章推荐
jquery分页插件AmSetPager(自写)
Apr 15 Javascript
网页广告中JS代码的信息监听示例
Apr 02 Javascript
javascript实现链接单选效果的方法
May 13 Javascript
JavaScript动态创建div等元素实例讲解
Jan 06 Javascript
Vuejs第十二篇之动态组件全面解析
Sep 09 Javascript
bootstrap datepicker 与bootstrapValidator同时使用时选择日期后无法正常触发校验的解决思路
Sep 28 Javascript
javascript入门之window对象【新手必看】
Nov 22 Javascript
浅谈React和Redux的连接react-redux
Dec 04 Javascript
JQuery实现table中tr上移下移的示例(超简单)
Jan 08 jQuery
微信小程序实现搜索历史功能
Mar 26 Javascript
vue实现网络图片瀑布流 + 下拉刷新 + 上拉加载更多(步骤详解)
Jan 14 Javascript
JavaScript实现队列结构过程
Dec 06 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
隐藏X-Space个人空间下方版权方法隐藏X-Space个人空间标题隐藏X-Space个人空间管理版权方法
2007/02/22 PHP
php魔法函数与魔法常量使用介绍
2017/07/23 PHP
Laravel框架查询构造器简单示例
2019/05/08 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
用正则获取指定路径文件的名称
2007/02/27 Javascript
javascript AOP 实现ajax回调函数使用比较方便
2010/11/20 Javascript
jquery实现按Enter键触发事件示例
2013/09/10 Javascript
解析JSON对象与字符串之间的相互转换
2013/12/18 Javascript
file控件选择上传文件确定后触发的js事件是哪个
2014/03/17 Javascript
JavaScript利用正则表达式去除日期中的“-”
2014/07/01 Javascript
纯HTML5制作围住神经猫游戏-附源码下载
2015/08/23 Javascript
jquery插件jquery.LightBox.js实现点击放大图片并左右点击切换效果(附demo源码下载)
2016/02/25 Javascript
javascript的 {} 语句块详解
2016/02/27 Javascript
浅析AngularJS中的指令
2016/03/20 Javascript
JSON键值对序列化和反序列化解析
2017/01/24 Javascript
Bootstrap modal只加载一次数据的解决办法(推荐)
2017/11/24 Javascript
Electron + vue 打包桌面操作流程详解
2019/06/24 Javascript
ElementUI Tree 树形控件的使用并给节点添加图标
2020/02/27 Javascript
使用纯前端JavaScript实现Excel导入导出方法过程详解
2020/08/07 Javascript
Python内存管理方式和垃圾回收算法解析
2017/11/11 Python
关于Tensorflow中的tf.train.batch函数的使用
2018/04/24 Python
python自制包并用pip免提交到pypi仅安装到本机【推荐】
2019/06/03 Python
python flask框架实现传数据到js的方法分析
2019/06/11 Python
python自动化UI工具发送QQ消息的实例
2019/08/27 Python
TensorFlow内存管理bfc算法实例
2020/02/03 Python
利用Node实现HTML5离线存储的方法
2020/10/16 HTML / CSS
巴西家用小家电购物网站:Polishop
2016/08/07 全球购物
法国隐形眼镜网站:VisionDirect.fr
2020/03/03 全球购物
大学生标准推荐信范文
2013/11/25 职场文书
新年抽奖获奖感言
2014/03/02 职场文书
小班评语大全
2014/05/04 职场文书
反邪教警示教育方案
2014/05/13 职场文书
班级文化标语
2014/06/23 职场文书
工商管理自荐书
2014/07/06 职场文书
自荐信模板大全
2015/03/27 职场文书
病假证明模板
2015/06/19 职场文书