概念:
事件就是用户在网页上的动作,例如:鼠标点击、鼠标移动、键盘按下…
事件三要素 : 事件源 + 事件名称 + 事件处理函数
- 事件源 : 谁触发这个事件 (按钮 btn)
- 事件名称 : 触发了什么事件 (点击click事件)
- 事件处理函数 :事件触发后要执行的代码
注意:事件处理程序(函数)并不是立马执行,而是当事件触发的时候在会执行(浏览器会自动调用)
1.事件类型:
(1)鼠标事件
事件 | 备注 |
---|---|
click | 单击 |
dblclick | 双击 |
contextmenu | 右击 |
mouseover | 移入(有冒泡) |
mouseout | 移出(有冒泡) |
mouseenter | 移入(没有冒泡) |
mouseleave | 移出(没有冒泡) |
mousedown | 按下 |
mouseup | 弹起 |
mousemove | 鼠标移动 |
mousewheel | 滑轮 |
(2)键盘事件
事件 | 备注 |
---|---|
keypress | 敲击键盘 |
keydown | 键盘按下 |
keyup | 键盘抬起 |
键盘事件可以区分按下的是哪个键,每个键都有按键码
window.onkeydown = function(e){
var keyNum = e.keyCode //e.keyCode获取键盘码
if(keyNum == "13"){
alert("回车键");
}else if(keyNum == "8"){
alert("BackSpace键");
}
}
e.keyCode有兼容问题:IE中使用e.which
兼容写法:var keycode = e.keyCode || e.which
(3)表单事件
事件 | 备注 |
---|---|
focus | 获取焦点 |
blur | 失去焦点 |
change | 内容改变 |
submit | 提交事件 |
oninput | 当文本框的内容发生改变时触发 |
onpropertychange | 兼容IE的oninput |
(4)window事件
事件 | 备注 |
---|---|
load | 页面中所有内容(html结构、图片资源、样式文件、js文件)都加载完成,再执行这个事件的函数 |
resize | 浏览器窗口大小发生改变的时候触发的事件 |
scroll | 浏览器的滚动条发生滚动的时候触发的事件(必须有滚动条才行) |
unload | 浏览器关闭时触发的事件 |
2.事件对象:
概念:
事件触发后,事件的具体描述信息。如:鼠标点击的位置、按键信息…
获取事件对象:
<body>
<button id="btn">按钮</button>
</body>
<script type="text/javascript">
btn.onclick=function(){
console.log(window.event);
}
</script>
还有另外一种写法:
btn.onclick=function(e){
console.log(e);
}
以前的时候,前面的写法是针对IE浏览器的,下面的写法是针对W3C标准浏览器的。上面的写法,现在基本都兼容了;下面这种写法,在IE低版本浏览器中还不兼容。
兼容所有浏览器的写法:
btn.onclick = function(e){
var e = e || window.event
console.log(e);
}
3.点击事件的鼠标坐标点:
(1)相对于子元素的坐标点
事件对象.offsetX
事件对象.offsetY
注意:元素可用区域的边缘到光标的位置,不计算边框。
<body>
<style>
#box{
width: 200px;
height: 200px;
border: 1px solid #000;
}
</style>
<div id="box"></div>
</body>
<script type="text/javascript">
box.onclick = function(e){
var e = e || window.event;
console.log(e.offsetX,e.offsetY);}
</script>
(2)相对于浏览器可视区域的坐标点
事件对象.clientX
事件对象.clientY
注意:只计算当前可视区域,不计算滚动条滚动过的距离。
<body>
<style>
#box{
width: 200px;
height: 200px;
border: 1px solid #000;
margin: 100px;
}
</style>
<div id="box"></div>
</body>
<script type="text/javascript">
box.onclick = function(e){
var e = e || window.event;
console.log(e.clientX,e.clientY);}
</script>
(3)相对于整个页面的绝对位置
事件对象.pageX
事件对象.pageY
注意:包含滚动过的距离。
事件对象.pageX =事件对象.clientX +document.documentElement.scrollLeft
事件对象.pageY =事件对象.clientY +document.documentElement.scrollTop
<body>
<style>
#box{
width: 20px;
border: 1px solid #000;
margin: 100px;
}
</style>
<div id="box">
没有什么能够阻挡
你对自由的向往
天马行空的生涯
你的心了无牵挂
穿过幽暗的岁月
也曾感到彷徨
当你低头的瞬间
才发觉脚下的路
心中那自由的世界
如此的清澈高远
盛开着永不凋零
蓝莲花
</div>
</body>
<script type="text/javascript">
box.onclick = function(e){
var e = e || window.event;
console.log(e.pageY);
}
</script>
4.事件流:
事件流:
事件从开始触发到执行函数,到事件结束之间的过程
事件流总共分为3个阶段:
- 捕获阶段 - 在找目标元素(从外层元素向内层元素)
- 目标阶段 - 找到目标函数,执行他的事件函数
- 冒泡阶段 - 执行目标函数之后,离开目标(由目标元素向外层元素)
5.事件的绑定和解绑:
使用on来绑定事件有弊端:同一个事件只能给一个元素绑定一次。
<body>
<button id="btn">按钮</button>
</body>
<script>
btn.onclick=function(){
console.log("第一次单击");
}
btn.onclick=function(){
console.log("第二次单击");
}
</script>
解绑事件:使用on绑定的就用on解绑:
btn.onclick = null;//移除绑定的单击事件
使用事件监听器绑定事件解决:
元素.addEventListener(type,handler,useCapture);
# type:给元素绑定的事件类型(事件类型不加on),如:click,mouseover...
# handler:处理事件的函数
# useCaptyre:可选;是否在冒泡阶段执行
true在捕获阶段执行
false在冒泡阶段执行(默认false)
IE兼容:元素.attachEvent('on' + type,handle);
移除监听:
元素.removeEventListener(eventType, handler, useCapture)
# eventType :事件类型(不要加on)
# handler:事件处理函数(监听函数)
# useCapture:可选;布尔值,指定事件是否在捕获或冒泡阶段执行。
true:事件监听函数在捕获阶段执行
false:事件监听函数在冒泡阶段执行(默认fasle)
IE兼容:元素.detachEvent(eventType, handler);
注意:如果事件处理函数handler是有名函数,则可以通函数名来移除,匿名函数无法移除。
事件绑定的兼容写法:
function addEvent(obj,type,handle){
try{// Chrome、FireFox、Opera、Safari、IE9.0及其以上版本
obj.addEventListener(type,handle,false);
}catch(e){
obj.attachEvent('on' + type,handle);=// IE8.0及其以下版本
}
}
try...catch的结构表示先执行try中的内容,如果try中内容发生了错误,再执行catch中的内容。这种语法结构的本意是用来测试一段代码的执行并捕获错误在catch中抛出的。我们可以利用这种结构来达到兼容的写法:try中的代码无法执行的时候,会执行catch中的代码,那么就在catch中执行另一种写法。
function bind(ele,type,handler){
if(ele.addEventListener){
ele.addEventListener(type,handler,false);
}else if{
ele.attachEvent("on+type",handler)
}else{
ele["on" + type] = handler;
}
}
事件解绑的兼容写法:
function unbind(ele,type,handler){
if(ele.removeEventListener){
ele.removeEventListener(type,handler,false);
}else if{
ele.detachEvent("on+type",handler)
}else{
ele["on" + type] = null;
}
}
6.事件的冒泡:
通过一个例子来看事件的冒泡:
<body>
<style>
#big{
width: 200px;
height: 200px;
border:1px solid #000;
}
#middle{
width: 150px;
height: 150px;
background: #abcdef;
}
#small{
width: 100px;
height: 100px;
background: red;
}
</style>
<div id="big">大盒子的内容
<div id="middle">中盒子的内容
<div id="small">小盒子的内容
</div>
</div>
</div>
</body>
<script type="text/javascript">
big.onclick=function(){
console.log(this.innerText);
console.log("大盒子的内容完毕");
}
middle.onclick=function(){
console.log(this.innerText);
console.log("中盒子的内容完毕");
}
small.onclick=function(){
console.log(this.innerText);
console.log("小盒子的内容完毕");
}
</script>
点击小盒子,发现小盒子事件完毕后,中盒子的事件也被触发了,接着大盒子的事件也被触发了。这就是事件冒泡的现象。也就是说,事件冒泡指的是事件从目标元素触发后,会向上冒泡,触发父元素的事件。
使用事件对象阻止冒泡:
e.stopPropagation(); // 大部分浏览器都支持
e.cancelBubble=true; // IE低版本浏览器
兼容写法:
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble=true;
}
eg:
small.onclick=function(e){
console.log(this.innerText);
console.log("小盒子的内容完毕");
var e = e || window.event;
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble=true;
}
--}