事件对象
- 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传进响应函数
- 实参名字可自定义,不是一定要用event
- 可以不设置实参,但浏览器还是会将事件对象传进响应函数,设置实参是为了使用方便
- 在事件对象中封装了当前事件相关的一切信息,比如:鼠标坐标、键盘哪个按键被按下,鼠标滚轮方向等...
举例:
一、鼠标在红色区域移动,在黄色区域显示鼠标坐标。
<html>
<head>
<title></title>
<style type="text/css">
#areaDiv{
width:300px;
height:100px;
background-color: red;
}
#showMsg{
width:300px;
height:20px;
background-color: yellow;
}
</style>
<script type="text/javascript">
window.onload=function(){
/*
实例:鼠标在红色区域移动,在黄色区域显示鼠标坐标。
*/
var areaDiv = document.getElementById("areaDiv");
var showMsg = document.getElementById("showMsg");
//onmousemove 鼠标在元素内移动时触发的事件
//事件对象
// - 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传进响应函数
// - 实参名字可自定义,不是一定要用event
// - 可以不设置实参,但浏览器还是会将事件对象传进响应函数,设置实参是为了使用方便
// - 在事件对象中封装了当前事件相关的一切信息,比如:鼠标坐标、键盘哪个按键被按下,鼠标滚轮方向等...
areaDiv.onmousemove = function(event){
/*
兼容性问题
- 在IE8及以下,事件被触发时,浏览器不会传递事件对象,而是将事件对象作为window对象的属性保存
*/
event = event || window.event;
/*
clientX获取鼠标指针的水平坐标
clientY获取鼠标指针的垂直坐标
*/
var x = event.clientX;
var y = event.clientY;
// 在showMsg中显示鼠标的坐标
showMsg.innerHTML = "x=" + x +",y=" + y;
}
}
</script>
</head>
<body>
<div id ="areaDiv"></div>
<div id = "showMsg"></div>
</body>
</html>
**结果**
二、div红色方块随鼠标移动
<html>
<head>
<title></title>
<style type="text/css">
body{
height:1000px;
}
#box1{
width:100px;
height:100px;
background-color:red;
position:absolute;
}
</style>
<script type="text/javascript">
window.onload=function(){
/*
实例:div跟随鼠标移动
*/
var box1 = document.getElementById("box1");
//onmousemove 鼠标在元素内移动时触发的事件
//事件对象
// - 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传进响应函数
// - 实参名字可自定义,不是一定要用event
// - 可以不设置实参,但浏览器还是会将事件对象传进响应函数,设置实参是为了使用方便
// - 在事件对象中封装了当前事件相关的一切信息,比如:鼠标坐标、键盘哪个按键被按下,鼠标滚轮方向等...
document.onmousemove = function(event){
/*
兼容性问题
- 在IE8及以下,事件被触发时,浏览器不会传递事件对象,而是将事件对象作为window对象的属性保存
*/
event = event || window.event;
/*
clientX获取鼠标指针的水平坐标,相对于可见窗口
clientY获取鼠标指针的垂直坐标,相对于可见窗口
var left = event.clientX;
var top = event.clientY;
有滚动条时会鼠标和方块分离
*/
/*
pageX获取鼠标指针的水平坐标,相对于整个页面
pageY获取鼠标指针的垂直坐标,相对于整个页面
兼容性问题:IE8不支持
var left = event.pageX;
var top = event.pageY;
*/
/*
解决兼容问题
chrome不支持document.body.scrollTop,支持document.documentElement.scrllTop
*/
//获取滚动条滚动的举例
var st = document.body.scrollTop||document.documentElement.scrollTop;
var sl = document.body.scrollLeft||document.documentElement.scrollLeft;
var left = event.clientX + sl;
var top = event.clientY + st;
box1.style.left = left + "px";
box1.style.top = top + "px";
}
}
</script>
</head>
<body>
<div id ="box1"></div>
</body>
</html>
事件的冒泡
- 所谓冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会触发
- 在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象event.cancelBubble来取消冒泡
举例:
一、body中设置一个div,div里设置一个span,当点击span区域时,点击事件也会传导到div和body。
<html>
<head>
<title></title>
<style type="text/css">
#box1{
width:200px;
height:300px;
background-color:green;
}
span{
background-color: red;
}
</style>
<script type="text/javascript">
window.onload=function(){
var box1 = document.getElementById("box1");
var s1 = document.getElementById("s1");
s1.onclick = function(){
alert("我是span单击响应函数");
}
box1.onclick = function(){
alert("我是box1单击响应函数");
}
document.body.onclick = function(){
alert("我是body的单击响应函数");
}
}
</script>
</head>
<body>
<div id ="box1">
我是box1
<span id="s1">我是span</span>
</div>
</body>
</html>
点击span区域,会弹出三个提示框
二、红色方块可以随鼠标移动并能进黑色区域
在【事件的对象举例二代码】中再增添如下代码:
<html>
<head>
<title></title>
<style type="text/css">
#block{
width: 500px;
height:500px;
background-color: black;
}
</style>
</head>
<body>
<div id="block"></div>
</body>
</html>
结果
三、红色方块可以随鼠标移动,但不能进黑色区域
在【上述二的代码】中再添加如下代码:
<script type="text/javascript">
window.onload=function(){
var block = document.getElementById("block");
block.onmousemove = function(event){
event =event||window.event; //解决兼容问题
event.cancelBubble = true; //取消黑色区域的冒泡
}
}
</script>
结果
事件的委派
- 指将事件统一绑定给元素的共同祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
- 事件委派利用了冒泡,通过委派可以减少事件绑定的次数,从而提高程序的性能
<html>
<head>
<title></title>
<style type="text/css">
}
</style>
<script type="text/javascript">
window.onload=function(){
var btn01 = document.getElementById("btn01");
var ul = document.getElementById("ul");
// 点击按钮添加超链接
btn01.onclick =function(){
//创建一个li
var li= document.createElement("li");
li.innerHTML = "<a href='javascript:;' class='link'>添加的超链接</a>";
//li添加到ul
ul.appendChild(li);
}
/*
方法一:为每一个超链接绑定一个单击响应事件
- 只能为已有的超链接绑定事件,后添加的无法绑定
*/
/*
方法二:【事件的委派】为超链接的祖先元素绑定一次单击响应事件,都可应用到后代超链接
ul.onclick = function(){
alert("点击了超链接");
}
*/
//优化事件的委派,如果触发事件的对象是我们期望的元素,才会执行
ul.onclick = function(event){
event=event||window.event;
//事件的属性target,返回触发事件的元素
if(event.target.className=="link"){
alert("点击了ul的链接");
}
}
}
</script>
</head>
<body>
<button id="btn01">点击添加链接</button>
<ul id="ul">
<li><a href="javascript:;" class='link'>这是已有的链接</a></li>
<li><a href="javascript:;" class='link'>这是已有的链接</a></li>
<li><a href="javascript:;" class='link'>这是已有的链接</a></li>
</ul>
</body>
</html>
事件的绑定(监听)
使用对象.事件=函数(【例如btn01.onclick =function(){}】的形式绑定响应函数,只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,即使绑定了多个,也只会执行最后面的响应函数,前面的都会覆盖。
通过事件的绑定,可以为一个元素的一个事件绑定多个响应函数,并且都会会执行。
示例:
一、为按钮绑定多个单击响应函数,即单击按钮后将触发多次单击响应函数
<html>
<head>
<title></title>
<style type="text/css">
}
</style>
<script type="text/javascript">
window.onload=function(){
var btn01 = document.getElementById("btn01");
/*
addEventListener(事件名称,回调函数,布尔值)
- 事件名称 ,不要on
- 回调函数,当事件触发时执行的函数
- 布尔值,是否在捕获阶段触发事件,一般都传false
兼容性问题,IE8不支持addEventListener(),只支持attachEvent()并且是反序执行
attachEvent(事件全称,回调函数)
- 事件全称,要on
- 并且这是window的方法,即attachvent()中的this是window
*/
/*
//addEventListener()
btn01.addEventListener("click",function(){
alert("[点击事件]第一个响应函数");
},false);
btn01.addEventListener("click",function(){
alert("[点击事件]第二个响应函数");
},false);
btn01.addEventListener("click",function(){
alert("[点击事件]第三个响应函数");
},false);
//attachEvent()
btn01.attachEvent("onclick",function(){
alert("[点击事件]第一个响应函数");
});
btn01.attachEvent("onclick",function(){
alert("[点击事件]第二个响应函数");
});
btn01.attachEvent("onclick",function(){
alert("[点击事件]第三个响应函数");
});
*/
/*解决兼容性问题
定义一个函数,用来指定元素绑定响应函数
bind(obj,eventstr,callback)
参数:
obj 要绑定事件的元素
eventstr 事件名称
callback 执行的回调函数
注意:统一两个方法的this
*/
bind(btn01,"click",function(){
alert("[点击事件]第一个响应函数");
});
bind(btn01,"click",function(){
alert("[点击事件]第二个响应函数");
});
bind(btn01,"click",function(){
alert("[点击事件]第三个响应函数");
});
}
/*解决兼容性问题
定义一个函数,用来指定元素绑定响应函数
bind(obj,eventstr,callback)
参数:
obj 要绑定事件的元素
eventstr 事件名称
callback 执行的回调函数
注意:
统一两个方法的this,大部分浏览器的this是调用事件的元素,IE8的this是window
this是谁由调用方式决定
*/
function bind(obj,eventstr,callback){
if(obj.addEventListener){
//大部分浏览器
obj.addEventListener(eventstr,callback,false);
}else{
//IE8及以下
obj.attachEvent("on"+eventstr,function(){
//让浏览器执行匿名函数,在匿名函数中调用callback指定this
callback.call(obj);
});
}
}
</script>
</head>
<body>
<button id="btn01">点我一下</button>
</body>
</html>
单击按钮后依次显示结果
事件的传播
事件的传播
关于事件的传播,W3C将事件传播分成了三个阶段
1、捕获阶段
- 在捕获阶段时,从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2、目标阶段
- 事件捕获到目标元素,捕获结束,开始在目标元素上触发事件
3、冒泡阶段
- 事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件
如果希望在捕获阶段触发事件,可以将addEventListener()的第三个参数设置为true,一般情况不会希望在捕获阶段触发事件,所以一般都设置false
另外,IE8及以下没有捕获阶段