JS 事件绑定、事件监听、事件委托详细介绍


Posted in Javascript onSeptember 28, 2016

在JavaScript的学习中,我们经常会遇到JavaScript的事件机制,例如,事件绑定、事件监听、事件委托(事件代理)等。这些名词是什么意思呢,有什么作用呢?

事件绑定

要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数。所谓事件处理函数,就是处理用户操作的函数,不同的操作对应不同的名称。

在JavaScript中,有三种常用的绑定事件的方法:

  1. 在DOM元素中直接绑定;
  2. 在JavaScript代码中绑定;
  3. 绑定事件监听函数。

在DOM中直接绑定事件

我们可以在DOM元素上绑定onclick、onmouseover、onmouseout、onmousedown、onmouseup、ondblclick、onkeydown、onkeypress、onkeyup等。好多不一一列出了。如果想知道更多事件类型请查看, DOM事件 。

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

<script>
function hello(){
 alert("hello world!");
}
</script>

在JavaScript代码中绑定事件

在JavaScript代码中(即 script 标签内)绑定事件可以使JavaScript代码与HTML标签分离,文档结构清晰,便于管理和开发。

<input type="button" value="click me" id="btn">

<script>
document.getElementById("btn").onclick = function(){
 alert("hello world!");
}
</script>

使用事件监听绑定事件

绑定事件的另一种方法是用 addEventListener() 或 attachEvent() 来绑定事件监听函数。下面详细介绍,事件监听。

事件监听

关于事件监听,W3C规范中定义了3个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段。

起初Netscape制定了JavaScript的一套事件驱动机制(即事件捕获)。随即IE也推出了自己的一套事件驱动机制(即事件冒泡)。最后W3C规范了两种事件机制,分为捕获阶段、目标阶段、冒泡阶段。IE8以前IE一直坚持自己的事件机制(前端人员一直头痛的兼容性问题),IE9以后IE也支持了W3C规范。

W3C规范

语法:

element.addEventListener(event, function, useCapture)

event : (必需)事件名,支持所有 DOM事件 。

function:(必需)指定要事件触发时执行的函数。

useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获。false,冒泡。默认false。

注:IE8以下不支持。

<input type="button" value="click me" id="btn1">

<script>
document.getElementById("btn1").addEventListener("click",hello);
function hello(){
 alert("hello world!");
}
</script>

IE标准

语法:

element.attachEvent(event, function)

event:(必需)事件类型。需加“on“,例如:onclick。

function:(必需)指定要事件触发时执行的函数。

<input type="button" value="click me" id="btn2">

<script>
document.getElementById("btn2").attachEvent("onclick",hello);
function hello(){
 alert("hello world!");
}
</script>

事件监听的优点

1、可以绑定多个事件。

<input type="button" value="click me" id="btn3">

<script>
var btn3 = document.getElementById("btn3");
btn3.onclick = function(){
 alert("hello 1"); //不执行
}
btn3.onclick = function(){
 alert("hello 2"); //执行
}
</script>

常规的事件绑定只执行最后绑定的事件。

<input type="button" value="click me" id="btn4">

<script>
var btn4 = document.getElementById("btn4");
btn4.addEventListener("click",hello1);
btn4.addEventListener("click",hello2);

function hello1(){
 alert("hello 1");
}
function hello2(){
 alert("hello 2");
}
</script>

两个事件都执行了。

2、可以解除相应的绑定

<input type="button" value="click me" id="btn5">

<script>
var btn5 = document.getElementById("btn5");
btn5.addEventListener("click",hello1);//执行了
btn5.addEventListener("click",hello2);//不执行
btn5.removeEventListener("click",hello2);

function hello1(){
 alert("hello 1");
}
function hello2(){
 alert("hello 2");
}
</script>

封装事件监听

<input type="button" value="click me" id="btn5">

//绑定监听事件
function addEventHandler(target,type,fn){
 if(target.addEventListener){
 target.addEventListener(type,fn);
 }else{
 target.attachEvent("on"+type,fn);
 }
}

//移除监听事件
function removeEventHandler(target,type,fn){
 if(target.removeEventListener){
 target.removeEventListener(type,fn);
 }else{
 target.detachEvent("on"+type,fn);
 }
}

//测试
var btn5 = document.getElementById("btn5");
addEventHandler(btn5,"click",hello1);//添加事件hello1
addEventHandler(btn5,"click",hello2);//添加事件hello2
removeEventHandler(btn5,"click",hello1);//移除事件hello1

事件委托

事件委托就是利用冒泡的原理,把事件加到父元素或祖先元素上,触发执行效果。

<input type="button" value="click me" id="btn6">

var btn6 = document.getElementById("btn6");
document.onclick = function(event){
 event = event || window.event;
 var target = event.target || event.srcElement;
 if(target == btn6){
 alert(btn5.value);
 }
}

上面只是个例子,代码尽可能的简化了。在实际的代码中 我们可能用到jQuery的live()、delegate()、bind()、on()等。

事件委托优点

1、提高JavaScript性能。事件委托可以显著的提高事件的处理速度,减少内存的占用。 实例分析JavaScript中的事件委托和事件绑定 ,这篇文章写得还不错。

传统写法

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>

<script>
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");

item1.onclick = function(){
 alert("hello item1");
}
item2.onclick = function(){
 alert("hello item2");
}
item3.onclick = function(){
 alert("hello item3");
}
</script>

事件委托

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>

<script>
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");

document.addEventListener("click",function(event){
 var target = event.target;
 if(target == item1){
 alert("hello item1");
 }else if(target == item2){
 alert("hello item2");
 }else if(target == item3){
 alert("hello item3");
 }
})
</script>

2、动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。

传统写法

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>

<script>
var list = document.getElementById("list");

var item = list.getElementsByTagName("li");
for(var i=0;i<item.length;i++){
 (function(i){
 item[i].onclick = function(){
 alert(item[i].innerHTML);
 }
 })(i)
}

var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);

</script>

点击item1到item3都有事件响应,但是点击item4时,没有事件响应。说明传统的事件绑定无法对动态添加的元素而动态的添加事件。

事件委托

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>

<script>
var list = document.getElementById("list");

document.addEventListener("click",function(event){
 var target = event.target;
 if(target.nodeName == "LI"){
 alert(target.innerHTML);
 }
})

var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);

</script>

当点击item4时,item4有事件响应。说明事件委托可以为新添加的DOM元素动态的添加事件。

 通过此文,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
JavaScript 动态生成方法的例子
Jul 22 Javascript
实现连缀调用的map方法(prototype)
Aug 05 Javascript
ie下jquery.getJSON的缓存问题的处理方法
Mar 29 Javascript
Jquery封装tab自动切换效果的具体实现
Jul 13 Javascript
基于javascript实现全国省市二级联动下拉选择菜单
Jan 28 Javascript
JS延时器提示框的应用实例代码解析
Apr 27 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
Jun 12 Javascript
AngularJs ng-repeat 嵌套如何获取外层$index
Sep 21 Javascript
vue里input根据value改变背景色的实例
Sep 29 Javascript
教你完全理解ReentrantLock重入锁
Jun 03 Javascript
微信小程序实现吸顶特效
Jan 08 Javascript
ES6学习笔记之let与const用法实例分析
Jan 22 Javascript
js创建对象几种方式的优缺点对比
Sep 28 #Javascript
AngularJS表单验证中级篇(3)
Sep 28 #Javascript
微信公众号 客服接口的开发实例详解
Sep 28 #Javascript
jQuery解析XML 详解及方法总结
Sep 28 #Javascript
iOS和Android用同一个二维码实现跳转下载链接的方法
Sep 28 #Javascript
微信小程序 实例应用(记账)详解
Sep 28 #Javascript
JavaScript 闭包详细介绍
Sep 28 #Javascript
You might like
ftp类(myftp.php)
2006/10/09 PHP
phpmyadmin打开很慢的解决方法
2014/04/21 PHP
详解WordPress中用于合成数组的wp_parse_args()函数
2015/12/18 PHP
laravel自定义分页效果
2017/07/23 PHP
JavaScript iframe的相互操作浅析
2009/10/14 Javascript
33个优秀的jQuery 教程分享(幻灯片、动画菜单)
2011/07/08 Javascript
js自执行函数的几种不同写法的比较
2012/08/16 Javascript
使用js正则控制input标签只允许输入的值
2013/07/29 Javascript
jQuery实现点击小图显示大图代码分享
2015/08/25 Javascript
基于BootStrap Metronic开发框架经验小结【三】下拉列表Select2插件的使用
2016/05/12 Javascript
Bootstrap弹出带合法性检查的登录框实例代码【推荐】
2016/06/23 Javascript
JS本地刷新返回上一页代码
2016/07/25 Javascript
jQuery 获取页面li数组并删除不在数组中的key
2016/08/02 Javascript
angularJs中datatable实现代码
2017/06/03 Javascript
JS去掉字符串前后空格、阻止表单提交的实现代码
2017/06/08 Javascript
package.json文件配置详解
2017/06/15 Javascript
详解动画插件wow.js的使用方法
2017/09/13 Javascript
微信小程序有旋转动画效果的音乐组件实例代码
2018/08/22 Javascript
bootstrap-treeview实现多级树形菜单 后台JSON格式如何组织?
2019/07/26 Javascript
小程序瀑布流组件实现翻页与图片懒加载
2020/05/19 Javascript
uni-app 自定义底部导航栏的实现
2020/12/11 Javascript
使用Python编写一个在Linux下实现截图分享的脚本的教程
2015/04/24 Python
Python删除windows垃圾文件的方法
2015/07/14 Python
11个Python Pandas小技巧让你的工作更高效(附代码实例)
2019/04/30 Python
Python 旋转打印各种矩形的方法
2019/07/09 Python
Python +Selenium解决图片验证码登录或注册问题(推荐)
2020/02/09 Python
Python+Selenium随机生成手机验证码并检查页面上是否弹出重复手机号码提示框
2020/09/21 Python
python palywright库基本使用
2021/01/21 Python
亚马逊印度站:Amazon.in
2017/10/15 全球购物
Etam俄罗斯:法国女士内衣和家居服网上商店
2019/10/30 全球购物
一套C#面试题
2013/10/09 面试题
Linux文件操作命令都有哪些
2015/02/27 面试题
AJax面试题
2014/11/25 面试题
经典优秀毕业生求职信范文分享
2013/12/18 职场文书
服务员自我评价
2014/01/25 职场文书
学校通报表扬范文
2015/05/04 职场文书