美文网首页
js的事件处理

js的事件处理

作者: 落花的季节 | 来源:发表于2017-07-24 15:27 被阅读23次

事件就是用户或浏览器自身执行的某种动作。比如说 click,mouseover,都是事件的名字。而相应某个事件的函数就叫事件处理程序(或事件侦听器)。为事件指定处理程序的方式有好几种。

事件的作用范围

//html
<div id="wrap">
    <div id="outer">
      <div id="inner"></div>
    </div>
  </div>
//css
#wrap {
  width: 200px;
  height: 200px;
  background: pink;
}
#outer {
  position: relative;
  top: 50px;
  left: 50px;
  width: 100px;
  height: 100px;
  background: #eeddff;
}
#inner {
  position: relative;
  top: 25px;
  left:25px;
  width: 50px;
  height: 50px;
  background: #44ddff;
}
//js
var wrap = document.getElementById('wrap');
wrap.addEventListener('click',function(){
  alert('789');
},false);
效果图

当点击粉色块和粉色外浅蓝色部分的时候,都弹出了789,而浅蓝色部分是嵌套在wrap元素之内的元素,故可得出结论,当元素注册了事件,此事件的作用范围为:1.元素自己所占页面空间部分加嵌套元素所占空间范围(若嵌套元素覆盖在容器元素上,则事件的作用范围为容器元素自身所占空间大小)

事件流

事件流描述的是从页面中接受事件的顺序。IE的事件流是事件冒泡流,而Netscape Communicator的事件流是事件捕获流。

冒泡事件

IE的事件流叫做事件冒泡(event bubbing),即事件右最具体的元素接受,然后逐级向上传播到不具体的元素,以下面的代码为例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <input type="button" value='click me' id='myBtn'>
</body>
</html>

如果你单击了#myBtn,那么在IE的页面中,这个事件会如下传播:

input->body->html->document

可以看到,事件首先在input上发生,input就是我们单击的元素。然后事件沿着DOM树向上传播,一直到document对象。
所有的现代浏览器都支持事件冒泡。IE9,Firefox,Chrome和Safari则将事件一直冒泡到window对象。

事件捕获

Netscape团队提出的另一种事件流叫事件捕获,事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。以上面的代码作为例子,那么单击div的时候会按照与冒泡相反的顺序触发事件。

document->html->body->input

在这个过程中,document对象先接收到click事件,然后事件沿着DOM树依次向下,一直传递到目标元素。
IE9,Firefox,Chrome和Safari都支持事件捕获。“DOM2级事件”规范要求事件应该从document对象开始传播,但实际上这些浏览器都是从window对象开始捕获事件。

DOM事件流

规定的事件流包括三个阶段:事件捕获阶段==>处于目标阶段==>事件冒泡阶段。首先发生的是事件捕获阶段,为截获事件提供了机会。然后是实际的目标接收事件。最后一个阶段是冒泡阶段。

DOM事件流

事件处理程序

HTML事件处理程序
<script type="text/javascript">   
function show(){   
alert('hello world!');   
}   
</script>   
<input type="button" value="click me" onclick="show()"/>  

在 html 中指定事件处理程序有两个缺点。

  • 存在一个时差问题。就本例子来说,假设 show()函数是在按钮下方,页面的最底部定义的,如果用户在页面解析 show()函数之前就单击了按钮,就会引发错误;
  • html 与 javascript 代码紧密耦合。如果要更换时间处理程序,就要改动两个地方:html 代码和 javascript 代码。
Javascript 指定事件处理程序

1.DOM0事件处理程序

var btn=document.getElementById("myBtn");   //获得对象元素的引用
btn.onclick=function(){
    alert("Clicked!");
}

要使用JavaScript指定事件处理程序,必须先获得对象元素的引用,然后为其指定事件处理程序的函数。
事件处理程序是在元素的作用域中运行的,也就是说程序中的this指向的是当前元素。

var btn=document.getElementById("myBtn");   //获得对象元素的引用
btn.onclick=function(){
    alert(this.id); //mybtn
}

通过将事件处理程序属性的值设置成null就可以删除事件处理程序。

btn.onclick = null;

2.DOM2级事件处理程序

“DOM2级事件”规定了两个方法用于操作事件处理程序:addEventListener()和removeEventListener()。所有的节点都包含这两个方法,接收三个参数:要处理的事件名,作为事件处理程序的函数和一个布尔值。最后的参数如果是true,表示在事件捕获阶段调用事件处理程序,如果是false,表示在事件冒泡阶段调用事件处理程序。

var btn=document.getElementById("myBtn");   
btn.addEventListener("click",function(){
    alert(this.id);
},false);

DOM0级事件处理程序只能为一个元素添加唯一的某一个事件的处理程序。如果为一个元素添加了两个click的处理程序,后定义的程序会覆盖掉之前定义的程序,其实也就是给变量a多次赋值一样。使用DOM2级事件处理程序的好处之一就是:可以添加多个添加多个事件处理程序。

var btn = document.getElementById('mybtn');
           btn.addEventListener('click',function () {
               alert('click me');
           },false)
            btn.addEventListener('click',function () {
                alert(this.id)
            },false);

这两个事件处理程序会按照添加的顺序触发。

通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除。通过addEventListener()添加的匿名函数无法移除,因为移除是传入的参数与添加处理程序时使用的参数必须相同。

function handle() {
            alert('hello world')
}
btn.addEventListener('click',handle,false);
btn.removeEventListener('click',handle,false);

大多数情况下,都是就事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种浏览器。

IE中的事件处理程序

IE中有类似于DOM的两个方法:attachEvent()和detachEvent()。这两个方法接受两个参数:事件处理程序名称和事件处理程序函数。attachEvent()添加的事件处理程序都会添加到冒泡阶段。

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

需要注意的是,这里传入的是‘onclick’而不是‘click’。
前面说到,在DOM0级事件中,事件处理程序的作用域是元素的作用域,而在使用attachEvent()时,作用域变成了全局作用域,此时this等于window

var btn=document.getElementById("myBtn");
btn.attachEvent("onclick",function(){
    alert(this==widnow);//"true"
});

与addEventListener()一样,attachEvent()也可以用来为一个元素添加多个事件处理程序,不过与DOM方法不同的是,事件处理程序不是按照添加的顺序执行,而是以相反的顺序执行。
可以使用detachEvent()移除使用attachEvent()添加的事件处理程序。与DOM方法一样必须提供相同的参数,添加的匿名函数不能被移除。

因此,跨域浏览器的事件处理程序可以这样写:

var EventUtil = {   
addHandler: function(element, type, handler){ // 该方法接受 3 个参数:要操作的元素,事件名称和事件处理程序函数   
if (element.addEventListener){ // 检查传入的元素是否存在 DOM2 级方法   
element.addEventListener(type, handler, false); // 若存在,则使用该方法   
} else if (element.addEvent){ // 如果存在的是 IE 的方法   
element.attachEvent("on" + type, handler); // 则使用 IE 的方法,注意,这里的事件类型必须加上 "on" 前缀。   
} else { // 最后一种可能是使用 DOM0 级   
element["on" + type] = hander;   
}   
},   

removeHandler: function(element, type, handler){ // 该方法是删除之前添加的事件处理程序   
if (element.removeEventListener){ // 检查传入的元素是否存在 DOM2 级方法   
element.removeEventListener(type, handler, false); // 若存在,则使用该方法   
} else if (element.detachEvent){ // 如果存在的是 IE 的方法   
element.detachEvent("on" + type, handler); // 则使用 IE 的方法,注意,这里的事件类型必须加上 "on" 前缀。   
} else { // 最后一种可能是使用 DOM0 及方法 (在现代浏览器中,应该不会执行这里的代码)   
element["on" + type] = null;   
}   
}   
};  
var btn =document.getElementById("mybtn");   
var hander= function(){   
alert("clicked");   
};   
 
EventUtil.addHandler(btn,"click",hander);   
 
EventUtil.removeHandler(btn,"click",hander); // 移除之前添加的事件处理程序  

参考资料:
https://segmentfault.com/a/1190000003497939
http://wiki.jikexueyuan.com/project/brief-talk-js/event-handlers.html

相关文章

  • JavaScript的事件机制详解

    【js事件详解】js事件封装函数,js跨浏览器事件处理机制 一、事件流 事件流描述的是从页面中接受事件的顺序。IE...

  • javascript 高级 -- jQuery-事件绑定

    事件的处理程序在js当中很重要的。事件驱动是js的重要组成部分。在js中,有html中处理程序,dom0级,dom...

  • JS事件处理

    鼠标事件 事件冒泡 控件随着鼠标移动 按键事件 基础 onkeydown、onkeyup、onkeypress 小...

  • js事件处理

    一. DOM0与DOM2事件处理程序 DOM0级 添加事件:通过在DOM元素的onxxx属性上添加处理程序重复添加...

  • js的事件处理

    事件就是用户或浏览器自身执行的某种动作。比如说 click,mouseover,都是事件的名字。而相应某个事件的函...

  • 事件处理程序

    HTML事件处理程序 HTML程序和JS无法分离 DOM0级事件处理程序 DOM2级事件处理程序 DOM2级事件定...

  • js中的事件

    简单总结一下js中的事件 事件处理程序 事件委托 各种各样的事件总结 事件中的this指向 事件处理程序 直接在D...

  • JS的事件绑定、事件监听、事件委托

    事件绑定: 要想让JS对用户的操作做出响应,首先要对DOM元素绑定 事件处理函数。所谓事件处理函数,就是处理用户操...

  • React 事件处理机制

    React在处理事件和HTML中JS处理事件不同,本文介绍React中的事件处理机制。React中不同通过返回fa...

  • js事件机制

    一、js事件机制三个阶段:事件捕获、事件目标处理函数、事件冒泡 js中事件执行的整个过程称之为事件流,分为三个阶段...

网友评论

      本文标题:js的事件处理

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