一、事件的定义和产生
JavaScript 与 HTML之间的交互是通过事件实现的。
事件:主要是对用户或者网页自身某种行为进行捕获和响应。例如:当我们点击表单提交按钮的时候,提交数据到服务器。首先DOM捕获到这一行为,并执行我们定义的提交数据的函数。
二:事件捕获和事件冒泡
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>JS事件处理程序</title> <link href="https://cdn.bootcss.com/skeleton/2.0.4/skeleton.min.css" rel="stylesheet"> </head> <body> <div class="wrapper" id="wrapper"> <button id="event">JS事件处理程序</button> </div> </html>
事件冒泡
IE的事件流,从内到外事件开始由目标元素接受然后逐级向外传播
如果单击了button 元素,那么这个click 事件 会按照这样的顺序传播
button>div>body>html>document
假如用户单击了一个元素,该元素拥有一个click事件,那么同样的事件也将会被它的祖先触发,这个事件从该元素开始一直冒泡到DOM树的最上层,这一过程称为事件冒泡
所有的浏览器都支持事件冒泡,IE5.5及其以前的版本会跳过<html>直接到document
Firfox、Chome、和 Safari 将事件一直持续到Window 对象
事件捕获
用户触发了一个事件的时候,这个事件是从DOM树的最上层开始触发一直到捕获到事件源.事件传播从外到内:如果单击了button 元素,那么这个click 事件 会按照这样的顺序传播
Document>>html>div>button
IE>=9 以上版本支持
三、 DOM事件流
”DOM2级事件“ 规定事件流包括三个阶段:事件捕获、处于目标阶段、事件冒泡阶段
首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段
四、事件处理程序
事件:用户或者浏览器自身的动作,比如click,load等都事件名称,而响应事件的函数就是事件处理程序。
事件处理程序一般由on 开头,比如 click的事件处理程序是onclick (不区分大小写)
五、事件绑定
Dom0 级
支持所有的浏览器,兼容性好,只能指定应该一个事件处理程序(函数),后面的会覆盖之前的。通过事件处理程序属性来绑定 属性名称通常小写。
var wrapper = document.getElementById("wrapper"),
event = document.getElementById("event");
event.onclick=function(){
alert("你好");
alert(this.id); //event
}
使用Dom0级方法指定的事件处理程序被认为是元素的方法,因此这个时候事件处理程序实在元素的作用域内执行,换句话说程序中 this只当前元素。
删除事件处理程序:设置未null: event.onclick=null;
Dom2级
非IE浏览器、IE9及以上的版本也支持
添加事件: addEventListener(要处理的事件名称,事件处理程序函数,true:事件捕获阶段执行;false:事件冒泡阶段执行);
删除事件: deleteEventListener(要处理的事件名称,事件处理程序函数,true:事件捕获阶段执行;false:事件冒泡阶段执行);
匿名函数没有办法删除;
这时候元素一个事件类型可以绑定多个事件
IE
添加事件:attachEvent(事件处理程序名称“on”开头,事件处理程序函数)
删除事件: detachEvent(事件处理程序名称“on”开头,事件处理程序函数)
事件处理程序再全局作用域中执行,事件处理程序函数中的this=window
可以为一个函数添加多个事件处理程序,事件处理程序执行顺序与事件添加的顺序相反
IE11 不支持
六、事件对象
在触发DOM元素上某个事件的时候会产生一个对象event,这个对象包含了所有与事件有关的信息。包含导致事件的元素,事件的类型,以及其它与事件相关的信息。所有的浏览器都支持event对象,但是支持方式不同。
实现方式:兼容DOM的浏览器会将一个event对象传到事件处理程序
IE9以下的版本 用Dom0 方式绑定的时候 从window对象获取 window.event
Event 对象包含与创建它的特定事件有关的属性和方法,触发的事件类型不同,可用的属性和方法也不同
但是所有事件都回包含下面的成员
属性和方法 |
描述 Event |
bubbles |
返回布尔值,指示事件是否是起泡事件类型。 |
cancelable |
返回布尔值,指示事件是否可拥可取消的默认动作。 |
currentTarget |
返回其事件处理程序当前正在处理事件的那个元素。 与this 相等。 |
eventPhase |
返回事件传播的当前阶段。1:捕获阶段,2:处于目标,3:冒泡阶段 |
target |
返回触发此事件的元素(事件的目标节点)。 |
type |
被触发事件的类型 |
view |
与事件关联的抽象试图。等同于发生事件的window对象 |
timeStamp |
返回事件生成的日期和时间。 |
initEvent() |
初始化新创建的 Event 对象的属性。 |
preventDefault() |
通知浏览器不要执行与事件关联的默认动作。比如链接跳转行为 |
stopPropagation() |
不再派发事件。取消事件的进一步捕获或者冒泡 |
|
|
this,target.currentTraget
- 在事件处理程序内部this始终等于currentTarget的值,target则只包含事件的实际目标
- 只有在事件处理程序执行期间,event对象才存在,一旦事件执行完毕,event对象就会被销毁。
- js中事件是会冒泡的,所以this是可以变化的,但event.target不会变化,它永远是直接接受事件的目标DOM元素;
其它属性和方法
属性 |
描述 |
altKey |
返回当事件被触发时,”ALT” 是否被按下。 |
button |
返回当事件被触发时,哪个鼠标按钮被点击。 |
clientX |
返回当事件被触发时,鼠标指针的水平坐标。 |
clientY |
返回当事件被触发时,鼠标指针的垂直坐标。 |
ctrlKey |
返回当事件被触发时,”CTRL” 键是否被按下。 |
metaKey |
返回当事件被触发时,”meta” 键是否被按下。 |
relatedTarget |
返回与事件的目标节点相关的节点。 |
screenX |
返回当某个事件被触发时,鼠标指针的水平坐标。 |
screenY |
返回当某个事件被触发时,鼠标指针的垂直坐标。 |
shiftKey |
返回当事件被触发时,”SHIFT” 键是否被按下。 |
- IE 属性(除了上面的鼠标/事件属性,IE 浏览器还支持下面的属性)
属性 |
描述 |
cancelBubble |
如果事件句柄想阻止事件传播到包容对象,必须把该属性设为 true。 |
fromElement |
对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。 |
keyCode |
对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup |
offsetX,offsetY |
发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。 |
returnValue |
如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为false 就可以取消元素的默认行为 |
srcElement |
对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。 |
toElement |
对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。 |
x,y |
事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。 |
针对以上情况可以封装跨浏览器的事件绑定,事件取消,
var EventUti={ //绑定事件 addHandler:function(element,type,handler) { if(element.addEventListener) { element.addEventListener(type,handler,false); }else if(element.attachEvent) { element.attachEvent(type,handler); }else { element["on"+type]=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; } }, getTarget:function(event) { return event.target||event.srcElement; }, //取消元素的默认行为 preventDefault:function(event) { if(event.preventDefault) { event.preventDefault(); }else { event.returnValue=false; //IE下 } }, //取消事件的捕获或者冒泡行为 stopPropagation:function(event){ if(event.stopPropagation) { event.stopPropagation(); }else { event.cancelBubble=true; } } }