文章目录
前言
JavaScript 事件
HTML 事件是发生在 HTML 元素上的事情。
当在 HTML 页面中使用 JavaScript 时, JavaScript 可以触发这些事件。
HTML 事件
HTML 事件可以是浏览器行为,也可以是用户行为。
以下是 HTML 事件的实例:
HTML 页面完成加载
HTML input 字段改变时
HTML 按钮被点击
通常,当事件发生时,你可以做些事情。
在事件触发时 JavaScript 可以执行一些代码。
HTML 元素中可以添加事件属性,使用 JavaScript 代码来添加 HTML 元素。
1 事件初识
事件可以用于处理表单验证,用户输入,用户行为及浏览器动作:
页面加载时触发事件
页面关闭时触发事件
用户点击按钮执行动作
验证用户输入内容的合法性
等等 …
<body>
<button id="btn">点击</button>
</body>
<script>
//节点.on事件名 = 匿名函数
document.getElementById("btn").onclick=function(){
alert("大海都是水")
}
</script>
2 为一个元素绑定多个事件(以鼠标点击事件为例)
绑定单个事件,写多个时,后面的会覆盖前面的:
节点.on事件名 = 匿名函数
绑定多个事件,写多个时,事件按顺序执行:
节点.attachEvent(“有on类型的事件/on事件名”,事件处理的函数,false) (谷歌、火狐不支持 IE8以下的浏览器支持 )
节点.addEventListener(“没有on的事件类型/事件名”,事件处理的函数,false)(谷歌、火狐支持 IE8以下不支持)
<body>
<button id="btn">点击</button>
</body>
2.1 为一个元素绑定单个事件
2.1.1 节点.on
<script>
//节点.on事件名 = 匿名函数
document.getElementById("btn").onclick=function(){
alert("大海都是水")//没有正常输出显示
}
document.getElementById("btn").onclick=function(){
alert("大海都是水001")//输出显示
}
</script>
2.2 为元素绑定多个事件:有两种写法
绑定多个事件的意思是可单可多
true - 事件句柄在捕获阶段执行
false- false- 默认。事件句柄在冒泡阶段执行(false可写可不写)
2.2.1 节点.attachEvent()(非主流用法)
谷歌不支持 火狐不支持IE8以下的浏览器支持
<script>
var btn = document.getElementById("btn")
btn.attachEvent("onclick",function(){
console.log("大海全是水")//测试使用的谷歌浏览器,无法输出
})
</script>
2.2.2 节点.addEventListener()
谷歌支持 火狐支持 IE8以下不支持 (支持目前的主流浏览器)
<script>
var btn=document.getElementById("btn")
btn.addEventListener("click",function(){
alert("大海全是水")//输出显示
},false)
btn.addEventListener("click",function(){
alert("大海全是水001")//输出显示
},false)
</script>
2.2.3 attachEvent和addEventListener之间的区别
相同点: 都可以为元素绑定事件
不同点:
1)方法名不一样
2)参数的个数是不一样的 attachEvent是两个参数 addEventListener是三个参数
3)addEventListener 谷歌 火狐 IE8 支持 attachEvent IE8以下支持
4)this指向不同 attachEvent中的指向是window addEventListener表示的是当前绑定事件的对象
5)一个加on 一个不加on
2.3 为元素绑定事件的兼容写法
<script>
var btn=document.getElementById("btn")
//为任意元素绑定事件 事件类型和事件处理函数
function addEventListener(element,type,fn){//元素,事件类型,匿名函数
//判断浏览器是否支持这个方法 谷歌 火狐 IE>8
if(element.addEventListener){
element.addEventListener(type,fn,false) //节点.addEventListener()
}else if(element.attactEvent){
//iE<=8
element.attactEvent("on"+type,fn) //节点.attachEvent()
}else{
element["on"+type]=fn //节点.οnclick=function(){}
}
}
addEventListener(btn,"click",function(){
alert("大海全是水")
})
addEventListener(btn,"click",function(){
alert("大海全是水001")
})
</script>
3 为一个元素解除绑定事件
(节点对象/元素对象)节点类和元素类在继承的原型中是相关的
3.1 解绑事件(on)
对象.on事件名 = 事件处理函数
对象.on事件名 = null
3.2 解绑事件(attactEvent())
对象.attactEvent(“on的事件类型”,命名函数)
对象.detachEvent(“on的事件类型”,命名函数)
3.3 解绑事件(addEventListener())
对象.addEventListener(“不加on的事件类型”,命名函数,false)
对象.removeEventListener(“不加on的事件类型”,命名函数,false)
btn2.onclick=function(){
//移出绑定事件
btn.onclick=null;
btn.detachEvent("click",fn1);
btn.removeEventListener("click",fn1,false);
}
3.4 解绑事件的兼容写法
经测试on的解绑必须写前面才能兼容全部,否则只执行remove的解绑(就无法解绑on的事件)。
<script>
var btn=document.getElementById("btn")
//为任意元素绑定事件 事件类型和事件处理函数
function addEventListener(element,type,fn){//元素,事件类型,匿名函数
//判断浏览器是否支持这个方法 谷歌 火狐 IE>8
if(element.onclick){
element["on" + type] = null
//console.log("调用了on的解绑");
}
else if (element.removeEventListener) {
element.removeEventListener(type,fnName,false)
//console.log("调用了remove的解绑");
//btn1.click(fn1);若是这种绑定倒是可以
}
else {
element.detachEvent("on" + type, fnName)
//console.log("调用了data的解绑");
}
}
addEventListener(btn,"click",function(){
alert("大海全是水")
})
addEventListener(btn,"click",function(){
alert("大海全是水001")
})
</script>
4 事件冒泡
事件冒泡: 多个元素嵌套 有层次关系 这些元素都注册了相同的事件 如果里边的元素事件触发了 外边的元素的事件就会自动触发(从内到外)
<!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>
#div1{
width:300px;
height:200px;
background-color: red;
}
#div2{
width:250px;
height:150px;
background-color: green;
}
#div3{
width:200px;
height:100px;
background-color: blue;
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">
<div id="div3"></div>
</div>
</div>
</body>
<script>
function $(id){
return document.getElementById(id)
}
$("div1").onclick=function(){
console.log(this.id) //div1
}
$("div2").onclick=function(){
console.log(this.id) //div2
}
$("div3").onclick=function(){
console.log(this.id) //div3
}
</script>
</html>
点击顺序是从蓝=>绿=>红 |
输出顺序是:点蓝色:div3 div2 div1
点绿色:div2 div1
点红色:div1
5 事件捕获
事件捕获: 多个元素嵌套 有层次关系 这些元素都注册了相同的事件 事件触发的形式是由外到内
<script>
function $(id){
return document.getElementById(id)
}
$("div1").addEventListener("click",function(){
console.log(this.id)
},true)
$("div2").addEventListener("click",function(){
console.log(this.id)
},true)
$("div3").addEventListener("click",function(){
console.log(this.id)
},true)
</script>
点击顺序是从蓝=>绿=>红 |
输出顺序是:点蓝色:div1 div2 div3
点绿色:div1 div2
点红色:div1
总结: addEventListener第三个参数的作用 false 冒泡 true捕获 |
6 阻止事件冒泡
如何阻止事件冒泡
IE浏览器特有的 谷歌火狐不支持 window.event.cancelBubble=true
e.stopPropagation() 谷歌和火狐支持
<script>
function $(id){
return document.getElementById(id)
}
$("div1").addEventListener("click",function(d){
console.log(this.id)
// d.stopPropagation();
},false)
$("div2").addEventListener("click",function(e){
console.log(this.id)
// e.stopPropagation();
},false)
$("div3").addEventListener("click",function(e){
console.log(this.id)
//阻止事件冒泡
// e.stopPropagation();
},false)
</script>
7 (获取/得知)事件阶段
可以通过e.eventPhase这个属性知道当前的事件是什么阶段的
eventPhase 属性返回事件传播的当前阶段。它的值是下面的三个常量之一,它们分别表示捕获阶段、正常事件派发和起泡阶段:
1 事件捕获阶段 由外到内
2 事件目标阶段 最开始选择的那个
3 事件冒泡阶段 从里到外
<script>
function $(id) {
return document.getElementById(id)
}
var objs = [$("div1"), $("div2"), $("div3")]
//遍历注册事件
for (var i in objs) {
console.log(i)
objs[i].addEventListener("click", function (e) {
console.log(this.id + "=======>" + e.eventPhase)
}, false)//false 冒泡 true捕获
// objs[i].οnclick= function (e) {//事件冒泡
// console.log(this.id + "=======>" + e.eventPhase)
// }
}
</script>
8 为一个元素绑定多个指向同一事件
为同一个元素绑定多个不同的事件 指向相同的事件处理函数
<body>
<input type="button" id="btn" value="金老师" >
</body>
<script>
function $(id) {//这个其实就是jquery常用的$符号的由来
return document.getElementById(id)
}
$("btn").onclick = f1
$("btn").onmouseover= f1
$("btn").onmouseout = f1
function f1(e){
//e.type能够获取事件类型
switch (e.type){
case "click":
console.log("0001")
break;
case "mouseover":
console.log("002")
break;
case "mouseout":
console.log("003")
break;
}
}
</script>
或者用addEvenListener():
<style>
#demo{
width:500px;
height:500px;
background-color: red;
}
</style>
</head>
<body>
<div id="demo"></div>
</body>
<script>
var demo=document.getElementById("demo")
demo.addEventListener("click",function(){
console.log("click")
},false)
demo.addEventListener("mousemove",function(){
console.log("mousemove")
},false)
demo.addEventListener("mouseout",function(){
console.log("mouseout")
},false)
</script>
9 总结
一 关于事件阶段
1 事件捕获阶段 由外到内
2 事件目标阶段 最开始选择的那个
3 事件冒泡阶段 从里到外
二 阻止事件冒泡
为元素绑定事件
addEventListener
事件触发的过程中 可能会出现事件冒泡 为了阻止事件冒泡
window.event.cancelBubble=true
window.event就是一个对象,是IE的标准
e.stopPropagetion() 阻止事件冒泡 ------ 谷歌火狐标准
window.event 和e都是事件参数对象 一个是IE标准 一个是火狐和谷歌标准
三 一般情况默认的都是冒泡 很少用捕获
可以通过 e.eventPhase 这个属性能够知道现在事件所处的阶段
冒泡阶段: 从里到外
捕获阶段: 从外向里