事件
概述
绑定事件
<button>按钮</button>
<script>
let btn = document.querySelector("button");
//以前绑定事件的方法 元素.on事件类型=function(){}
/*
btn.onclick = function(){
console.log("hello");
}
*/
//新的绑定事件方法 元素.addEventListener("事件类型",function(){})
btn.addEventListener("click",function(){
console.log("hello");
});
</script>
两者区别
<button>按钮</button>
<script>
let btn = document.querySelector("button");
/*
btn.onclick=function(){
console.log("hello click1")
}
btn.onclick=function(){
console.log("hello click2")
}//结果会输出hello click2
//通过赋值添加事件,后面的事件会覆盖掉前面的
*/
btn.addEventListener("click",function(){
console.log("hello click1")
})
btn.addEventListener("click",function(){
console.log("hello click2")
})
</script>
事件流
<!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>
.big{
width: 300px;
height: 300px;
background-color: red;
}
.middle{
width: 200px;
height: 200px;
background-color: blue;
}
.small{
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div class="big">
<div class="middle">
<div class="small"></div>
</div>
</div>
<script>
let big = document.querySelector(".big")
let middle = document.querySelector(".middle")
let small = document.querySelector(".small")
big.addEventListener("click",function(){
console.log("big")
})
middle.addEventListener("click",function(){
console.log("middle")
})
small.addEventListener("click",function(){
console.log("small")
})
</script>
</body>
</html>
结果说明事件触发是从内到外的,即在事件冒泡阶段
事件捕获与事件冒泡
big.addEventListener("click",function(){
console.log("big")
},true)
middle.addEventListener("click",function(){
console.log("middle")
},true)
small.addEventListener("click",function(){
console.log("small")
},true)
了解即可,绝大多数情况下都是在冒泡阶段执行事件
阻止事件冒泡e.stopPropagation()
阻止冒泡阶段触发多个事件
big.addEventListener("click",function(){
console.log("big")
})
middle.addEventListener("click",function(){
console.log("middle")
})
small.addEventListener("click",function(e){
console.log("small")
e.stopPropagation()
})
点击黄色区域,输出只有small,阻止了外层的事件执行
<!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>
.box{
width: 200px;
height: 200px;
background-color: yellow;
display: none;
}
</style>
</head>
<body>
<div class="show">
<button>显示</button>
</div>
<div class="box">
<div class="close">
<button>关闭</button>
</div>
</div>
<script>
let show = document.querySelector(".show")
let box = document.querySelector(".box")
let close = document.querySelector(".close")
show.addEventListener("click",function(){
box.style.display = "block"
})
close.addEventListener("click",function(){
box.style.display = "none"
})
box.addEventListener("click",function(){
box.style.backgroundColor = "red"
})
</script>
</body>
</html>
点击显示
现在有个bug,如果直接点关闭,再点显示,box的颜色也会变成红色
因为点击关闭触发close的事件,又因为close有外部事件box,所以也会触发box事件改变颜色
要避免这种情况就要在close事件加个e.stopPropagation()
close.addEventListener("click",function(e){
box.style.display = "none"
e.stopPropagation()
})
阻止事件默认行为e.preventDefault()/return false
<a href="http://baidu.com">baidu</a>
<script>
let baidu = document.querySelector("a")
baidu.addEventListener("click",function(){
console.log("baidu")
})
</script>
点击baidu就会跳转到baidu网页,同时在控制台输出baidu
如果只想输出baidu,那可以用e.preventDefault()
<a href="http://baidu.com">baidu</a>
<script>
let baidu = document.querySelector("a")
baidu.addEventListener("click",function(e){
console.log("baidu")
e.preventDefault()
})
</script>
另一种写法
<a href="http://baidu.com">baidu</a>
<script>
let baidu = document.querySelector("a")
baidu.onclick = function(e){
console.log("baidu")
return false//对addEventListener无效
}
</script>
事件委托
通过事件冒泡的原理,通过e.target将子级的事件委托给父级完成
<!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>
<input type="text">
<button>添加</button>
<ul class="fruits">
<li>苹果</li>
<li>香蕉</li>
<li>雪梨</li>
</ul>
<script>
let btn = document.querySelector("button")
let inp = document.querySelector("input")
let ul = document.querySelector(".fruits")
btn.addEventListener("click",function(){
let li = document.createElement("li")
let value = inp.value
let txt = document.createTextNode(value)
li.appendChild(txt)
ul.appendChild(li)
})
//事件委托
ul.addEventListener("click",function(e){
ul.removeChild(e.target)
/*e.target是触发该事件的子元素,这里是点击的li标签
因为点击li标签虽然li本身没有事件,但它的外层即父级有绑定点击事件
就是这里的ul事件
*/
})
</script>
</body>
</html>
通过事件委托的方法可以解决上一章节无法删除新添加的li标签的问题
事件类型
键盘事件
document.addEventListener("keydown",function(){
//keydown类型能通过按下任意键触发事件
console.log("hello")//按任意键打印hello
})
document.addEventListener("keydown",function(e){
console.log(e.keyCode)//输出按键对应的码值,且不区分大小写,如a和A=65
})
- 通过键盘移动方块
<!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>
.box{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
let box = document.querySelector(".box");
/*
offset方向:距离某个方向的偏移量
console.log(box.offsetTop);//100 距离上侧的偏移量是100px
console.log(box.offsetLeft);//100 距离左侧的偏移量是100px
*/
document.addEventListener("keydown",function(e){
let code = e.keyCode//左上右下的键值是37,38,39,40
switch(code){
case 37:
box.style.left = box.offsetLeft - 5 + "px";
break;
case 38:
box.style.top = box.offsetTop - 5 + "px";
break;
case 39:
box.style.left = box.offsetLeft + 5 + "px";
break;
case 40:
box.style.top = box.offsetTop + 5 + "px";
break;
}
});
</script>
</body>
</html>
触屏事件
<style>
.box{
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
let box = document.querySelector(".box");
box.addEventListener("touchstart",function(){
//touchstart是手机的触屏后(手指抬起前)会触发事件
console.log("start");
});
box.addEventListener("touchend",function(){
//touchend是手指抬起屏幕后会触发事件
console.log("end");
});
box.addEventListener("touchmove",function(){
//touchmove是手指按住屏幕并移动时(即划动屏幕)会触发事件
console.log("move");
});
</script>
</body>
</html>