一、事件绑定
1.1 HTML标签事件绑定
在HTML标签内绑定事件,相当于在标签内执行一段代码:
<button onclick="show();print();alert('123')" id="btn1">html标签事件绑定</button>
注意:
1、通过HTML标签绑定事件函数,实质上就是在标签内运行多行JS代码。
2、在标签内绑定事件函数,事件函数中的this指的是window对象。
3、在标签内绑定事件函数,事件函数可以传入参数。
可以传入任意参数。
也可以传入this对象,代表当前标签对象。
1)通过HTML标签绑定事件函数,实质上就是在标签内运行多行JS代码
<script>
function show(){
alert('456')
}
function show2(){
alert('789')
}
</script>
<body>
<button onclick="alert('123');show();show2()"> 点我一下</button>
</body>
2)在标签内绑定事件函数,事件函数中的this指的是window对象
<script>
function show(){
console.log(this)
}
</script>
</head>
<body>
<button onclick="show();"> 点我一下</button>
</body>
3)在标签内绑定事件函数,事件函数可以传入任意参数,也可以传入this对象。
>>>>>> 可以给绑定的函数传入任意参数
<script>
function show(str){
console.log(str);
}
</script>
</head>
<body>
<button onclick="show('123');"> 传入字符串</button>
</body>
>>>>>> 可以给绑定的函数传入this对象,这里的this对象指的就是标签本身。
<script>
function show(obj){
console.log(obj);
}
</script>
</head>
<body>
<button onclick="show(this);"> 传入this</button>
</body>
1.2 JS事件绑定
1、绑定一个匿名函数
elem.onclick=function(){
alert("1")
}
2、绑定一个已经声明的函数
function show(){
console.log('show');
}
//绑定一个已经声明的函数
elem.onclick=show;
注意:
1、JS事件绑定,事件函数中的this指的是绑定的对象。
2、只能为一个事件绑定一个响应函数,不能绑定多个。
如果绑定多个,则后面绑定的响应函数会覆盖之前的响应函数。
3、JS事件绑定,事件函数中的this指的是绑定的元素。
1)JS事件绑定
<body>
<button > 绑定匿名函数</button>
<button > 绑定已经声明的函数</button>
</body>
<script>
/** 绑定匿名函数*/
var btn=document.getElementsByTagName("button")[0]
btn.onclick=function(){
alert("123")
}
/** 绑定已经声明的函数*/
function show(){
alert("123")
}
var btn1=document.getElementsByTagName("button")[1]
btn1.onclick=show;
</script>
2)只能为一个事件绑定一个响应函数,不能绑定多个。否则会覆盖
<body>
<button> 点我一下</button>
</body>
<script>
var btn=document.getElementsByTagName("button")[0];
btn.onclick=function(){
alert("0")
}
btn.onclick=function(){
alert("1")
}
//会覆盖前面绑定的事件函数
btn.onclick=function(){
alert("2")
}
</script>
3)JS事件绑定,事件函数中的this指的是绑定的元素
1.3 事件监听
+++ IE8以上浏览器事件监听
elem.addEventListener("click",function(){},false);
第一个参数:事件的字符串, 不用on
第二个参数:回调函数,当事件触发时会调用该回调函数
第三个参数:默认为false,表示是否捕获阶段触发。
1、IE8以上浏览器支持
2、可以同时为一个事件绑定多个响应函数。
当事件被触发时,响应函数将会按照绑定的顺序正序执行。
3、事件函数中的this指的是元素本身
+++ IE8以及以下浏览器事件监听
elem.attachEvent("onclick",function(){});
第一个参数:事件的字符串, 要on
第二个参数:回调函数,当事件触发时会调用该回调函数
1、IE8以及以下浏览器支持
2、可以同时为一个事件绑定多个响应函数。
当事件被触发时,响应函数将会按照绑定的顺序倒序执行。
3、事件函数中的this指的是window。
+++ 事件监听兼容性处理
function bind(obj,eventStr,calFun){
if(obj.addEventListener){
//兼容IE8以上浏览器
obj.addEventListener(eventStr,calFun);
}else{
//兼容IE8以及以下浏览器
obj.attachEvent("on"+eventStr,function(){
//改变函数中的this对象
calFun.apply(obj);
})
}
}
1)addEventListener事件监听
>>>>>> 可以绑定多个响应函数。按照顺序正序执行(仅支持IE8以上浏览器)
<body>
<button > 事件监听</button>
</body>
<script>
var btn=document.getElementsByTagName("button")[0]
btn.addEventListener("click",function(){
alert("123")
})
btn.addEventListener("click",function(){
alert("456")
})
btn.addEventListener("click",function(){
alert("789")
})
</script>
2)attachEvent事件监听
>>>>>> 可以绑定多个响应函数。按照顺序倒叙执行(仅支持IE8以及以下浏览器)
<body>
<button > 事件监听</button>
</body>
<script>
var btn=document.getElementsByTagName("button")[0]
btn.attachEvent("onclick",function(){
alert("123")
})
btn.attachEvent("onclick",function(){
alert("456")
})
btn.attachEvent("onclick",function(){
alert("789")
})
</script>
3)监听事件兼容性处理
如果事件监听要处理兼容性,
则我们需要考虑:addEventListener和attachEvent的this指向问题。
1、addEventListener中的this指的的元素本身
2、attachEvent中的this指的是window对象。
function bind(obj,eventStr,calFun){
if(obj.addEventListener){
//兼容IE8以上浏览器
obj.addEventListener(eventStr,calFun);
}else{
//兼容IE8以及以下浏览器
obj.attachEvent("on"+eventStr,function(){
//改变函数中的this对象
calFun.apply(obj);
})
}
}
>>>>>> 案例
<body>
<button > 事件监听</button>
</body>
<script>
/** 事件监听兼容性处理*/
function bind(obj,eventStr,calFun){
if(obj.addEventListener){
//兼容IE8以上浏览器
obj.addEventListener(eventStr,calFun);
}else{
//兼容IE8以及以下浏览器
obj.attachEvent("on"+eventStr,function(){
//改变函数中的this对象
calFun.apply(obj);
})
}
}
var btn=document.getElementsByTagName("button")[0]
bind(btn,"click",function(){
alert("123")
})
bind(btn,"click",function(){
alert("456")
})
bind(btn,"click",function(){
alert("789")
})
</script>
二、事件对象
事件对象(event):
1) 在事件对象中封装了当前事件相关的一切信息。比如:鼠标的坐标、按键值等
2) 在IE8以上浏览器
当事件回调函数被触发时,
浏览器每次都会将一个事件对象作为一个实参传递给回调函数。
3) 在IE8以及以下浏览器
事件对象会被当作window的属性来保存。
4) Event对象是在事件触发时就会存在的对象。
它有很多实现类,比如MouseEvent、FocusEvent等。我们可以访问event对象来访问事件相关的众多属性。
5) 事件对象和触发的事件有关系。事件对象类型不同,事件对象中的属性也有可能不同,
比如点击事件click,则事件对象是 MouseEvent。该对象中无key、keyCode属性
比如键盘事件keydown,则事件对象是 KeyboardEvent。该对象有key、keyCode属性。
1.1 事件对象的使用
1)在IE8以上浏览器,事件对象会被当做一个实参传入到事件回调函数中
当事件回调函数被触发时,浏览器会将一个事件对象作为实参传入回调函数中。由于arguments会接收所有的参数,我们打印arguments对象来查看传入的event对象。
var box1=document.getElementById("box1")
box1.onclick=function(){
console.log(arguments[0])
}
我们可以定义一个变量来接收传入的event对象
var box1=document.getElementById("box1");
box1.onclick=function(event){
console.log(event)
}
2)在IE8以及以下浏览器,事件对象会被当做window的属性来保存。
var box1=document.getElementById("box1");
box1.onclick=function(){
//MouseEvent {isTrusted: true, screenX: 339, screenY: 517, clientX: 97, clientY: 32, …}
console.log(window.event);
}
3)事件对象的兼容性处理
+++ 方式一:
var box1=document.getElementById("box1");
box1.onclick=function(event){
//兼容性处理
if(!event){
event=window.event;
}
console.log(event)
}
+++ 方式二:
var box1=document.getElementById("box1");
box1.onclick=function(event){
//兼容性处理
event=event || window.event;
console.log(event)
}
1.2 事件的坐标属性(通过事件对象获取触发事件时的鼠标的坐标)
获取触发事件的鼠标坐标,主要看坐标的原点在哪里
+++ 获取鼠标相对于窗口的坐标
event.clientX
event.clientY
获取鼠标相对于窗口的水平坐标、垂直坐标
(0,0)零点永远都在浏览器的左上端。
注意:使用该属性来实现【DIV元素随鼠标移动】,
如果页面没有滚动条,则可以实现。
如果页面有滚动条,则实现不了。原因是通过该属性获取的坐标是相对于窗口,而不是页面。
+++ 获取鼠标相对于页面的坐标
方式一:
event.pageX
event.pageY
获取鼠标相对于页面的水平坐标、垂直坐标。
(0,0)零点永远都在页面的左上端。
只支持IE8以上浏览器
方式二:
event.clientX + scrollLeft
event.clientY + scrollTop
获取鼠标相对于页面的水平坐标、垂直坐标。
兼容所有浏览器。
注意:这里隐藏了一个恒等式,即
event.clientX + document.body.scrollLeft = pageX
event.clientY + document.body.scrollTop = pageY
+++ 获取鼠标相对于事件元素左上角的坐标
event.offsetX
event.offsetY
获取鼠标相对于事件元素左上角的坐标
(0,0)零点永远都在事件元素的左上端。
1)获取鼠标相对于窗口的坐标
//给文档绑定移动事件
document.onmousemove=function(event){
//事件对象兼容性处理
event=event || window.event;
//获取鼠标相对于窗口的水平坐标、垂直坐标
console.log("x:"+event.clientX+" ,y:"+ event.clientY);
}
2)获取鼠标相对于页面的坐标
>>>>>> DIV元素随鼠标移动【使用pageX、pageY实现】【只支持IE8以上浏览器】
pageX、pageY可以获取鼠标相对于页面的坐标,所以我们可以通过获取该值来设置元素的移动。
不过,该属性只支持IE8以上浏览器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload=function(){
var box1=document.getElementById("box1");
//给html标签绑定移动事件
document.documentElement.onmousemove=function(event){
event=event || window.event;
var left=event.pageX;
var top=event.pageY ;
// var left=event.clientX + document.body.scrollLeft;
// var top=event.clientY + document.body.scrollTop;
box1.style.left=left+"px";
box1.style.top=top+"px";
}
}
</script>
</head>
<body>
<div id="box1" style="width:100px;height:100px;border:1px solid red;position:absolute;"></div>
</body>
</html>
>>>>>> DIV元素随鼠标移动【兼容性处理,支持所有浏览器】
我们使用clientX、clientY获取的坐标是鼠标相对于浏览器的坐标。
而元素的左右定位是相对于页面的坐标。
这里隐藏了一个等式,即
clientX+scrollLeft = pageX
clientY+scrollTop = pageY
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload=function(){
var box1=document.getElementById("box1");
//给html标签绑定移动事件
document.documentElement.onmousemove=function(event){
event=event || window.event;
var left=event.clientX + document.body.scrollLeft;
var top=event.clientY + document.body.scrollTop;
box1.style.left=left+"px";
box1.style.top=top+"px";
}
}
</script>
</head>
<body>
<div id="box1" style="width:100px;height:100px;border:1px solid red;position:absolute;"></div>
</body>
</html>
3)获取鼠标相对于事件元素左上角
event.offsetX
event.offsetY
获取鼠标相对于事件元素左上角的坐标
(0,0)零点永远都在事件元素的左上端。
1.3 事件对象的键盘属性(按键事件对象)
altKey 返回当事件被触发时,"ALT" 是否被按下。
ctrlKey 返回当事件被触发时,"CTRL" 键是否被按下。
metaKey 返回当事件被触发时,"meta" 键是否被按下。
shiftKey 返回当事件被触发时,"SHIFT" 键是否被按下。
button 返回当事件被触发时,哪个鼠标按钮被点击。
key 返回按键在系统中默认的名称
keyCode 返回按键在系统中的值。
>>>>>> 案例1
document.onkeydown=function(event){
if(event.altKey){
alert("alt键被按下")
return;
}
if(event.ctrlKey){
alert("ctrl键被按下")
return;
}
if(event.shiftKey){
alert("shift键被按下")
return;
}
if(event.metaKey){
alert("meta键被按下")
return;
}
}
>>>>>> 案例2:获取按键的名称和键值
<body>
<input type="text" id="btn" >
<script>
var obj= document.getElementById("btn")
obj.onkeydown=function(event){
console.log(event.key,event.keyCode)
}
</script>
</body>
1.4 事件对象的target属性
event.target
获取当前获取触发事件的元素对象。
<body>
<input type="text" id="btn" >
<script>
var obj= document.getElementById("btn")
obj.onkeydown=function(event){
console.log(event.target)
}
</script>
1.5 拖拽案例
1)案例1
缺点:拖拽元素时只能拖拽左上角
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width:100px;
height:100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
var div=document.getElementsByTagName("div")[0];
//给DIV添加鼠标按下事件
div.onmousedown=function(){
//鼠标按下时绑定鼠标移动事件
document.onmousemove=function(event){
event=event||window.event;
//获取鼠标相对于页面的坐标
var x=event.pageX;
var y=event.pageY;
div.style.left=x+"px";
div.style.top=y+"px";
}
//鼠标按下时绑定鼠标抬起事件
document.onmouseup=function(){
//取消移动事件
document.onmousemove=null;
//取消鼠标抬起事件
document.onmouseup=null;
}
}
</script>
</html>
2)案例2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width:100px;
height:100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
var div=document.getElementsByTagName("div")[0];
//给DIV添加鼠标按下事件
div.onmousedown=function(){
//鼠标的相对于页面的坐标 - 元素的偏移量
var ox=event.pageX-div.offsetLeft;
var oy=event.pageY-div.offsetTop;
//鼠标按下时绑定鼠标移动事件
document.onmousemove=function(event){
event=event||window.event;
//获取鼠标相对于页面的坐标
var x=event.pageX-ox;
var y=event.pageY-oy;
div.style.left=x+"px";
div.style.top=y+"px";
}
//鼠标按下时绑定鼠标抬起事件
document.onmouseup=function(){
//取消移动事件
document.onmousemove=null;
//取消鼠标抬起事件
document.onmouseup=null;
}
}
</script>
</html>
3)案例3(基于案例2的封装)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin:0px;
padding:0px;
}
.dd{
width:100px;
height:100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div class="dd">box1</div>
<div class="dd">box2</div>
<div class="dd">box3</div>
</body>
<script>
function drag(elem){
//给DIV添加鼠标按下事件
elem.onmousedown=function(){
//鼠标的相对于页面的坐标 - 元素的偏移量
var ox=event.pageX-elem.offsetLeft;
var oy=event.pageY-elem.offsetTop;
//给document添加一个鼠标移动事件
document.onmousemove=function(event){
event=event||window.event;
//获取鼠标相对于页面的坐标
var x=event.pageX-ox;
var y=event.pageY-oy;
elem.style.left=x+"px";
elem.style.top=y+"px";
}
//给document添加一个鼠标抬起事件
document.onmouseup=function(){
//取消移动事件
document.onmousemove=null;
//取消鼠标抬起事件
document.onmouseup=null;
}
}
}
var box1=document.getElementsByClassName("dd")[0]
drag(box1)
var box2=document.getElementsByClassName("dd")[1]
drag(box2)
var box3=document.getElementsByClassName("dd")[2]
drag(box3)
</script>
</html>
三、事件的冒泡
+++ 事件冒泡
1、所谓的冒泡指的就是事件触发会向上传导。
当后代的事件被触发时,其祖先相同的事件也会被触发。
2、事件冒泡具有两面性。不能单纯的说好坏。
+++ 阻止事件冒泡
方式一:
box2.onclick=function(event){
//取消冒泡
event=event || window.event;
event.cancelBubble=true;
alert("我是box2的单击响应函数");
}
方式二:
box2.onclick=function(event){
//取消冒泡
event=event || window.event;
event.stopPropagation();
alert("我是box2的单击响应函数");
}
注意:阻止冒泡就是是阻止子元素的事件冒泡,
所以阻止冒泡要加在子元素绑定的事件函数中。
1)事件冒泡
所谓的事件冒泡指的就是当我点击box2时,触发了box2的点击事件。同时也触发了box2的祖先元素box1的相同事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1{
width:500px;
height:500px;
background-color: red;
}
.box2{
width:300px;
height:300px;
background-color: blue;
}
</style>
<script>
window.onload=function(){
var box1=document.getElementsByClassName("box1")[0];
var box2=document.getElementsByClassName("box2")[0];
box1.onclick=function(){
alert("我是box1的单击响应函数")
}
box2.onclick=function(){
alert("我是box2的单击响应函数");
}
}
</script>
</head>
<body>
<div class="box1">
<div class="box2"></div>
</div>
</body>
</html>
2)阻止事件冒泡
阻止事件冒泡指的是阻止后代元素box2的事件触发导致祖先元素box1的事件触发。此时点击后代元素box2,只会触发box2绑定的事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1{
width:500px;
height:500px;
background-color: red;
}
.box2{
width:300px;
height:300px;
background-color: blue;
}
</style>
<script>
window.onload=function(){
var box1=document.getElementsByClassName("box1")[0];
var box2=document.getElementsByClassName("box2")[0];
box1.onclick=function(){
alert("我是box1的单击响应函数")
}
box2.onclick=function(event){
//取消冒泡
event=event || window.event;
event.cancelBubble=true;
alert("我是box2的单击响应函数");
}
}
</script>
</head>
<body>
<div class="box1">
<div class="box2"></div>
</div>
</body>
</html>
3)冒泡的意义
1、元素不绑定事件函数也可以触发事件。
只不过是没有事件回调函数去处理。
2、如果元素没有后代元素,那么元素的事件触发,就是本身的事件触发。
如果元素有后代元素,那么元素的事件触发,实质上可能是由于后代元素(鼠标指向的后代元素)的事件触发冒泡所致。
>>>>>> 以【DIV元素随鼠标移动】案例为例
给document对象绑定鼠标移动事件回调函数。
当鼠标移动到红色盒子上时,document对象的移动事件回调函数也被调用。
实质上是由于红色盒子的鼠标移动事件冒泡,从而触发了document的鼠标移动事件。
如果我们阻止红色盒子的事件冒泡,
那么就会出现鼠标在红色盒子上移动,不会触发document的鼠标移动事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin:0px;
padding:0px;
}
.box1{
width:500px;
height:500px;
background-color: red;
}
.box2{
width:100px;
height:100px;
background-color: blue;
position: absolute;
}
</style>
<script>
window.onload=function(){
var box2=document.getElementsByClassName("box2")[0];
//给document对象绑定鼠标移动事件回调函数
document.onmousemove=function(event){
//兼容性处理
event=event||window.event;
var left=event.clientX + document.body.scrollLeft;
var top=event.clientY + document.body.scrollTop;
box2.style.left=left+"px";
box2.style.top=top+"px";
}
//阻止box1的鼠标移动事件冒泡
var box1=document.getElementsByClassName("box1")[0];
box1.onmousemove=function(event){
event=event||window.event;
event.cancelBubble=true;
}
}
</script>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>
</html>
四、事件的委派
+++ 事件委派
1、事件委派利用了事件冒泡机制。通过祖先元素的绑定的事件函数来处理后代元素的事件。
2、通过事件委派可以减少事件绑定的次数。只绑定一次,即可应用到多个元素上。提高运行的效率。
3、将事件统一绑定给元素的共同的祖先元素,后代元素的事件触发,通过冒泡,就会导致祖先元素的事件也会被触发。
这样就可以通过祖先元素的事件函数来处理事件。
【所谓的事件委派机制,我的理解更像是一种编程方式。】
+++ 事件委派的实现
1、将事件统一绑定给元素的共同的祖先元素。
2、在事件函数中通过event.target来访问触发事件的实际对象。
(实际对象指的就是鼠标指向的对象。由于该对象的事件触发,并向上冒泡,从而导致祖先元素的事件触发)
ul.onclick=function(event){
event=event||window.event;
console.log(event.target)
//通过event.target来访问触发事件的实际对象
alert(event.target.innerHTML)
}
1)事件委派的来源
for循环给元素绑定事件函数,绑定次数过多,会造成资源的浪费。
给a标签设置点击事件。只能重复绑定。并且只能为已有的a标签设置事件。对于新增加的a标签,只能再次添加才可以。
<body>
<button> 添加超链接</button>
<ul>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
</ul>
</body>
<script>
//点击按钮,新增li标签
var btn=document.getElementsByTagName("button")[0];
var ul=document.getElementsByTagName("ul")[0];
btn.onclick=function(){
var li=document.createElement("li");
li.innerHTML='<a href="javascript:;">百度</a>';
ul.appendChild(li);
}
//给a标签添加事件
var aElems=document.querySelectorAll("ul li a");
for(var i=0;i<aElems.length;i++){
aElems[i].onclick=function(){
alert("123");
}
}
</script>
</html>
2)事件委派
1、给元素的共同的祖先元素绑定一个事件,
当触发子元素的事件时,通过冒泡就会触发祖先元素的事件函数。通过祖先元素的事件函数来进行处理。
2、在事件函数我们可以通过event.target来操作触发事件实际的对象。
>>>>>> 事件委派
<body>
<button> 添加超链接</button>
<ul>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
</ul>
</body>
<script>
//事件委派
var ul=document.querySelectorAll("ul")[0];
ul.onclick=function(event){
event=event||window.event;
console.log(event.target)
//我们可以通过event.target来访问触发事件的实际对象
alert(event.target.innerHTML)
}
</script>
>>>>>> 解析
a标签的点击事件被触发,通过冒泡从而导致祖先元素ul的点击事件被触发。
我们在ul绑定的点击事件中,
可以通过event.target来访问触发事件的实际对象(就是鼠标指向的对象)。
3)事件委派案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button> 添加超链接</button>
<ul>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
<li><a href="javascript:;">百度</a></li>
</ul>
</body>
<script>
//事件委派机制
//给a标签共同的祖先元素绑定事件
//当触发a标签的点击事件时,通过冒泡就会触发祖先元素的事件函数。
//我们通过祖先元素的事件函数来相应处理。
var ul=document.querySelectorAll("ul")[0];
ul.onclick=function(event){
event=event||window.event;
console.log(event.target)
//通过event.target来访问触发事件的实际对象
alert(event.target.innerHTML)
}
//点击按钮,新增li标签
var btn=document.getElementsByTagName("button")[0];
var ul=document.getElementsByTagName("ul")[0];
btn.onclick=function(){
var li=document.createElement("li");
li.innerHTML='<a href="javascript:;">百度</a>';
ul.appendChild(li);
}
</script>
</html>
五、事件的传播
4.1 事件的传播方式
关于事件的传播,微软公司和网景公司有不同的理解。
1) 微软公司认为事件应该由内向外传播。
当事件触发时,先触发当前元素(鼠标指向的元素)的事件,
然后在向当前元素的祖先元素传播。也就说事件在冒泡阶段执行。
2) 网景公司认为事件应该由外向内传播。
当事件触发时,先触发当前元素(鼠标指向的元素)的最外层的祖先元素的事件,
然后在向内传播给后代元素。
3) W3C综合了两家公司方案。将事件传播分为三个阶段。
1、捕获阶段
在捕获阶段时,从最外层的祖先元素向目标元素进行事件的捕获,
但是默认此时不触发事件。
2、目标阶段
事件捕获到目标元素,这是就是目标阶段。
捕获结束开始在目标元素上触发事件。
3、冒泡阶段
事件触发由目标元素向它的祖先元素传递。
【由外向内捕获,由内向外触发。默认情况下在目标阶段触发事件,然后向外冒泡。】
4.2 手动设置事件触发的阶段
我们可以通过addEventListener的第三个参数来设置事件触发的阶段。
1) 如果我们希望事件触发在捕获阶段,则
elem.addEventListener("click",function(){},true);
2) 如果我们希望事件触发在目标阶段(默认就是),则
elem.addEventListener("click",function(){}); //可不传。第三个参数默认为false
elem.addEventListener("click",function(){},false);
>>>>>> 设置事件触发在捕获阶段
点击box3,首先进入捕获阶段,从box3的祖先元素开始捕获。
由于设置了捕获阶段触发事件,所以先触发box3的祖先元素的box1的事件,然后box2事件,box3事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1{
width:500px;
height: 500px;
background-color: red;
}
.box2{
width:400px;
height: 400px;
background-color: blue;
}
.box3{
width:300px;
height: 300px;
background-color: pink;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2">
<div class="box3"></div>
</div>
</div>
</body>
<script>
var divs=document.getElementsByTagName("div");
var box1=divs[0];
var box2=divs[1];
var box3=divs[2];
box1.addEventListener("click",function(){
alert("我是box1")
},true)
box2.addEventListener("click",function(){
alert("我是box2")
},true)
box3.addEventListener("click",function(){
alert("我是box3")
},true)
</script>
<script>
</script>
</html>
>>>>>> 设置事件触发在目标阶段(默认就是)
点击box3,首先进入捕获阶段,从box3的祖先元素box1开始捕获。直到box3。
然后触发box3的事件。
然后冒泡。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1{
width:500px;
height: 500px;
background-color: red;
}
.box2{
width:400px;
height: 400px;
background-color: blue;
}
.box3{
width:300px;
height: 300px;
background-color: pink;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2">
<div class="box3"></div>
</div>
</div>
</body>
<script>
var divs=document.getElementsByTagName("div");
var box1=divs[0];
var box2=divs[1];
var box3=divs[2];
box1.addEventListener("click",function(){
alert("我是box1")
},false)
box2.addEventListener("click",function(){
alert("我是box2")
},false)
box3.addEventListener("click",function(){
alert("我是box3")
},false)
</script>
<script>
</script>
</html>
六、浏览器的默认行为
+++ 浏览器的默认行为
浏览器的默认行为指的是浏览器本身自带的属性,比如
1、a标签的自动跳转。
a标签的自动跳转是a标签的onclick事件的默认行为。
2、滑轮滚动,网页如果有滚动条也自动滚动
滚动条滚动是标签的onmousewheel事件的默认行为。
3、在文本框中输入内容属于onkeydown事件的默认行为。
+++ 取消浏览器的默认行为
1) 取消浏览器的默认行为,这种方式只适用于通过addEventListener绑定的事件函数。
elem.onclick=function(event){
//调用preventDefault方法,取消浏览器的默认行为
event.preventDefault()
}
2) 取消浏览器的默认行为,这种方式适用于通过HTML标签、JS绑定的事件函数
elem.onclick=function(event){
//返回false,取消浏览器的默认行为
return false;
}
3) 取消浏览器默认行为,兼容性处理
elem.onclick=function(event){
//调用preventDefault方法,取消浏览器的默认行为
event.preventDefault()
//返回false,取消浏览器的默认行为
return false;
}
2.1 取消a标签的默认行为
取消a标签的默认行为,此时点击a标签就不会跳转。
方式一:
<a href="javascript:;">百度</a>
方式二:
var aElem=document.getElementsByTagName("a")[0]
aElem.onclick=function(event){
event.preventDefault();
return false;
}
2.2 取消滑轮滚动的默认行为
取消滑轮滚动的默认行为,此时滑动滚轮,浏览器如果有滚动条,就不会滑动了
var div=document.getElementsByTagName("div")[0]
div.onmouseWheel=function(event){
event.preventDefault();
return false;
}
>>>>>> 滚动滑轮,div的高度发生变化,但是浏览器滚动条不会滚动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height:2000px">
<div style="width:100px;height: 100px;background-color: red; position: absolute;"></div>
</body>
<script>
var div=document.getElementsByTagName("div")[0];
document.onmousewheel=function(event){
event=event||window.event;
//向上滚动
if(event.wheelDelta>0){
div.style.height=(div.scrollHeight-10)+"px";
}
//向下滚动
if(event.wheelDelta<0){
div.style.height=(div.scrollHeight+10)+"px";
}
return false;
}
</script>
</html>
2.3 在文本框中只能输入英文
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height:2000px">
<input type="text">
</body>
<script>
var input=document.getElementsByTagName("input")[0];
input.onkeydown=function(event){
event=event||window.event;
console.log(event.keyCode)
if(event.keyCode < 65 || event.keyCode >90){
return false;
}
}
</script>
</html>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。