JavaScript 事件
目标
理解什么是事件
事件流
事件类型
事件的概念
事件指可以被 JavaScript 侦测到的行为。即鼠标点击、页面或图像载入、鼠标悬浮于页面的某个热点之上、在表单中选取输入框、确认表单、键盘按键等操作。事件通常与函数配合使用,当事件发生时函数才会执行。 事件名称:click/mouseover/blur("不带on")
响应某个事件的函数就是事件处理程序(事件侦听器)。 事件处理程序函数名称:onclick/onmouseove/onblur
比如说,当用户单击按钮时,就发生一个鼠标单击(onclick)事件,需要浏览器做出处理,返回给用户一个结果。 事件类型:
JavaScript
事件驱动:在js中,很多地方都是通过事件触发来驱动函数执行,从而实现某些功能。 脚本语言:在网络前端开发环境下,能够嵌入在浏览器端中的一段小程序叫做脚本语言。
事件流
事件发生时,会在发生事件的元素节点与DOM数根节点之间按照特定的顺序进行传播,这个过程称为事件流 事件流指从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。
事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。
1、两种事件流模型
事件传播的顺序对应浏览器的两种事件流模型:捕获型事件流和冒泡型事件流。 冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根【推荐】 捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。
IE的事件流是事件冒泡,而Netscape的事件流是事件捕获,为了解决页面中事件流(事件发生顺序)的问题 事件冒泡的概念下在p元素上发生click事件的顺序应该是p -> div -> body -> html -> document
事件捕获的概念下在p元素上发生click事件的顺序应该是document -> html -> body -> div -> p [
后来 w3c 采用折中的方式,平息了战火,制定了统一的标准——先捕获再冒泡。
一般地,将事件流分为三个阶段:捕获阶段,目标阶段和冒泡阶段。
事件绑定
方法一 HTML事件处理程序 <button onclick="fn()"></button>
-
方法二:DOM0级事件处理程序 ele.onxxx = function(){} 兼容性很好,但是不允许同一个对象,多次绑定同一个事件 基本上等同于写在行间上
<script> var btn = document.getElementById('btn'); btn.onclick = function(){ alert(1) } </script>```
方法三:DOM2级事件处理程序 obj.addEventListener(type,fn,false); IE9一下不兼容,允许同一个对象,多次绑定同一个事件 第一个参数是事件名(如click); 第二个参数是事件处理程序函数; 第三个参数如果是true则表示在捕获阶段调用,为false表示在冒泡阶段调用
<script>
var btn = document.getElementById('btn');
btn.addEventListener('click',function(){
alert(1);
})
+ 方法四
obj.attachEvent('on'+type,fn){}
IE独有,允许同一个对象,多次绑定同一个事件
btn.attachEvent('onclick',function(){
alert(1);
})
</script>```
事件处理程序分为三类:DOM0级事件处理程序、DOM2级事件处理程序、IE事件处理程序
* DOM0事件处理程序 //添加 btn.onclick = function(){} //移除 btn.onclick = null;
* DOM2事件处理程序 var handler = function(){} //添加 btn.addEventListener('click', handler,true/false); //移除 btn.removeEventListener('click', handler);
* IE 事件处理的程序 var handler = function(){} //添加 btn.attachEvent("onclick", handler); //移除 btn.removeEvent("onclick", handler);
```window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.addEventListener('click',function(){
console.log('btn处于事件捕获阶段');
}, true);
oBtn.addEventListener('click',function(){
console.log('btn处于事件冒泡阶段');
}, false);
document.addEventListener('click',function(){
console.log('document处于事件捕获阶段');
}, true);
document.addEventListener('click',function(){
console.log('document处于事件冒泡阶段');
}, false);
document.documentElement.addEventListener('click',function(){
console.log('html处于事件捕获阶段');
}, true);
document.documentElement.addEventListener('click',function(){
console.log('html处于事件冒泡阶段');
}, false);
document.body.addEventListener('click',function(){
console.log('body处于事件捕获阶段');
}, true);
document.body.addEventListener('click',function(){
console.log('body处于事件冒泡阶段');
}, false);
};```
#### 事件冒泡
冒泡:同一个事件,同一个冒泡到父元素
```<body>
<div id="content">content
<div id="btn">button</div>
</div>
<script type="text/javascript">
var content = document.getElementById("content");
var btn = document.getElementById('btn');
btn.onclick = function(){
alert("btn");
};
content.onclick = function(){
alert("content");
};
document.onclick = function(){
alert("document");
}
</script>
</body>
</html>```
注意:一个对象的一个事件类型只能存在一个事件模型(要么冒泡要么捕获)
#### 如何获取一个事件对象
DOM中,给事件处理函数一个参数e,e就是事件对象(非IE浏览器) 该参数不需要我们传递,来源于系统传递,它上面有很多的属性,每一个属性都记载着该事件发生时的关键性数据。
在IE浏览器下可以 var event = window.event;
兼容写法 var event = e||window.event;
事件对象上右一个专门的信息是记录事件源的。
事件源对象: event.target 火狐只有这个 event.srcElement IE只有这个
兼容写法: var target = event.target||event.srcElement;
#### 阻止事件冒泡
<!-- 案例;点击文字 弹出框 点击body弹框消失 -->
```var div = document.getElementById("div");
var a = document.getElementById("a");
a.onclick = function(e){
div.style.display = "block";
}
document.body.onclick = function(){
div.style.display = "none";
}```
方法: event.stopPropagation(); event.cancelBubble(); 兼容写法
``` function stopPropagation(e){
if(e && e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelBubble = true;
}
}```
#### 阻止默认事件
```默认事件--a标签跳转 右键菜单
<a href = 'Javascript:void(0)'></a>
return false; 取消默认行为的执行
e.preventDefault(); DOM提供的标准方法
e.returnValue = false;
```javascript
var link = document.getElementById("link");
link.onclick = function(e){
alert("hello");
}
// 右键单击的事件叫菜单事件
document.oncontextmenu = function(ev){
ev.preventDefault(); //阻止默认行为
var div = document.createElement("div");
div.style.width = "100px";
div.style.height = "100px";
div.style.background = "green";
div.style.position = "absolute";
div.style.left = event.clientX+"px"
div.style.top = event.clientY+"px";
document.body.appendChild(div);
}
document.onclick = function(){
document.body.lastChild.remove(); //lastChild 最后一个节点
}
兼容写法:
function stopDefault(e){
if(e && e.preventDefault){
e.preventDefault();
}else{
window.event.returnValue = false;
}
}
事件委托
ul.onclick = function(e){
var event = e||window.event;
var target = event.srcElement||event.target;
console.log(target);
}```
## Event对象的概念
```JavaScript与HTML的交互是通过用户或浏览器操作页面时发生的事件(Event)来处理的。
当页面加载时,它被称为事件(Event)。当用户单击按钮时,单击也是一个事件(Event)。其他示例包括按任意键、关闭窗口、调整窗口大小等事件(Event)。
我们可以使用这些事件(Event)来执行JavaScript的响应,比如响应按钮、向用户显示消息、验证数据,等等。
事件(Event)是文档对象模型(DOM)级别3(原文:Document Object Model (DOM) Level 3)的一部分,每个HTML元素都包含一组可以触发JavaScript代码的事件(Event)。
Event对象
Event对象相关属性
button 返回当事件被触发时,哪个鼠标按钮被点击。
clientX 返回当事件被触发时,鼠标指针的水平坐标。
clientY 返回当事件被触发时,鼠标指针的垂直坐标。
ctrlKey 返回当事件被触发时,”CTRL” 键是否被按下。
metaKey 返回当事件被触发时,”meta” 键是否被按下。
relatedTarget 返回与事件的目标节点相关的节点。
screenX 返回当某个事件被触发时,鼠标指针的水平坐标。
screenY 返回当某个事件被触发时,鼠标指针的垂直坐标。
shiftKey 返回当事件被触发时,”SHIFT” 键是否被按下。
cancelBubble 如果事件句柄想阻止事件传播到包容对象,必须把该属性设为 true。
fromElement 对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。
keyCode 对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup
offsetX,offsetY 发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。
returnValue 如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为
srcElement 对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。
toElement 对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。
x,y 事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。
Event对象相关方法
srcElement/target:事件源,就是发生事件的元素;
relatedTarget:返回与事件的目标节点相关的节点;
fromElement,toElement:对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素,toElement引用移入鼠标的元素;
currentTarget:返回其事件监听器触发该事件的元素;
timeStamp:返回事件生成的日期和时间;
eventPhase:返回事件传播的当前阶段,1表示捕获阶段,2表示处于目标,3表示冒泡阶段;
detail:表示的是与事件相关的细节信息
bubbles:返回布尔值,指示事件是否是起泡事件类型;
cancelable:返回布尔值,表示是否可以取消事件的默认行为;
cancelBubble:一个布尔属性,默认是false。把它设置为true的时候,将阻止事件进一步起泡到包容层次的元素;(e.cancelBubble = true; 相当于 e.stopPropagation();)
returnValue:一个布尔属性,设置为false的时候可以阻止浏览器执行默认的事件动作;(e.returnValue = false; 相当于 e.preventDefault();)
defaultPrevented:表示是否调用了preventDefault()
initEvent(eventType,canBubble,cancelable):初始化新创建的 Event 对象的属性;
preventDefault(): 通知浏览器不要执行与事件关联的默认动作;
stopPropagation():不再派发事件
DOM0级事件处理程序
分为2个:一是在标签内写onclick事件
二是在JS写onlick=function(){}函数
DOM2级事件处理程序
只有一个:监听方法,有两个方法用来添加和移除事件处理程序:addEventListener()和removeEventListener()。
它们都有三个参数:第一个参数是事件名(如click);
第二个参数是事件处理程序函数;
第三个参数如果是true则表示在捕获阶段调用,为false表示在冒泡阶段调用。
addEventListener():可以为元素添加多个事件处理程序,触发时会按照添加顺序依次调用。 removeEventListener():不能移除匿名添加的函数。
IE事件处理程序
IE中采用的事件流是事件冒泡,先从具体的接收元素,然后逐步向上传播到不具体的元素。
事件类型
UI事件
追踪用户在页面中的各种行为,如监听表单的输入 focus(获得焦点) blur(失去焦点),与表单的各种交互,submit change select
焦点事件
onfocus 事件在对象获得焦点时发生。 onblur 事件会在对象失去焦点时发生。
鼠标事件
跟踪鼠标当前定位(mouseover mouseout),跟踪鼠标单击(mouseup mousedown click)
click
用户单击鼠标主按钮(一般为左边按钮)或者在获得焦点的前提下按回车键时触发。 click()方法也可以触发click 事件。
dblclick
dblclick用户双击鼠标主按钮(一般为左边按钮)时触发。 mousedown:按下任意鼠标按钮时触发。 mouseup:释放鼠标按钮时触发。
mouseenter
鼠标光标从元素外部首次移动到元素范围之内时触发,这个事件不冒泡,而且在光标移动到后代元素上不会重复触发。通常和mouseleave搭配使用。 mousemove:鼠标光标在元素内部移动时重复地触发。 mouseover:鼠标光标位于一个元素外部,首次移动到另一个元素边界之内(包括后代元素)时触发。
键盘事件
keyup keydown keypress