事件的概念
事件
元素在某种状态(某种状态由浏览器实现也称为事件触发)达成时,要执行的提前设定好的程序,称之为事件句柄。
事件三要素
1.事件源:在哪个元素上发生的。比如: p标签、a标签、div标签、form表单等
2.事件类型:到底发生了什么事件。click(点击事件)、mouseover(鼠标事件)、focus(焦点事件)等
3.事件处理程序(handler):事件源触发事件后,如何回应发生的事件,通常以函数(funtion)的形式来出现,要执行的提前设定好的程序。
ps:1.事件不是以 on 开头的那个名称,如 onclick 不是事件,click才是事件。onclick引用的是一个元素对象的属性,它指向click事件类型绑定的实际处理函数。
2.事件三要素缺一不可
事件的绑定
事件绑定的方式有3种:行内式,元素属性绑定,给元素添加一个事件监听器。
行内式
行内式是直接在html元素上进行绑定,即以属性的方式直接写在行内。
<div class="box1">
<button class="btn1" onclick="test();fn()">方式1</button>
</div>
<script>
function test(){
console.log("test函数执行成功");
};
function fn(){
console.log("fn函数执行成功");
};
</script>
代码演示效果
1.标签的属性值是事件触发时执行的代码,可以绑定多个事件处理程序,用分号隔开即可,按照顺序执行。
2.标签的属性值在事件没有触发前就是一串字符串,当事件触发后才是事件触发时执行的代码,js的执行引擎就会运行这个函数体中的代码。
缺点:HTML与js代码紧密相关。如果要更换事件,需要改动两个地方:HTML代码和JS代码,这就不利于后期代码的维护。
元素属性绑定
用元素.on事件=某个函数 绑定,需要先获取要绑定的元素。
<div class="box2">
<button class="btn2">方式2</button>
</div>
<script>
let btn=document.querySelector(".btn2");
btn.onclick=()=>{
console.log("点击事件触发成功");
};
</script>
同一个 dom 元素上,on 只能绑定一个同类型事件,后者会覆盖前者,不同类型的事件可以绑定多个。
<div class="box2">
<button class="btn2">方式2</button>
</div>
<script>
let btn=document.querySelector(".btn2");
btn.onclick=()=>{
console.log("点击事件触发成功");
};
btn.onclick=()=>{
console.log("同类型事件会后者覆盖了前者");
};
给元素添加事件监听器
给元素添加一个事件监听器(就是函数),同样需要先获取元素
同一个 dom 元素上,用 addEventListener()、attachEvent() 可以绑定多个同类型事件且行内的属性值也不会被覆盖。但是,addEventListener 事件执行顺序按照事件绑定的先后顺序执行;attachEvent 事件执行顺序则是随机的。
事件监听是唯一可以改变[事件的传播]方式的绑定方法,只用在第三个参数加上true,这样默认在冒泡阶段执行就会变为在捕获阶段执行
addEventListener()以及其参数
addEventListener()是异步非阻塞函数,异步非阻塞函数只能由官方提供,自定义的回调函数是异步阻塞函数。
第1个参数:是字符串填写事件类型名称,没有on。比如onclick ,onmouseover等
第2个参数:是回调函数作为事件处理程序的函数。当事件触发时才会调用回调函数,执行事件处理程序函数中的函数体
第3个参数:是布尔值。若为false,函数在冒泡阶段执行;若为true,函数在捕获阶段执行。可选参数,不填默认为false。
<div class="box3">
<button class="btn3">方式3</button>
</div>
<script>
let btn=document.querySelector(".btn3");
btn.addEventListener("click",()=>{
console.log("事件被触发");
});
</script>
attachEvent()
attachEvent有兼容问题,谷歌火狐不支持以及IE11不支持,低版本的IE8支持。(目前IE浏览器已被淘汰)
addEventListener、attachEvent的区别
1)参数个数不一致
addEventListener三个参数,attachEvent两个参数
2)兼容问题
addEventListener 谷歌,火狐,IE11支持,IE8不支持
attachEvent 谷歌火狐不支持,IE11不支持,IE8支持
3)this指向不同
addEventListener 中的this是当前绑定事件的对象
attachEvent中的this是window
4)事件命名不同
addEventListener中事件的类型(事件的名字)没有on
attachEvent中的事件的类型(事件的名字)有on
解决兼容问题
<button id="btn">btn</button>
<script>
//为任意元素.绑定任意的事件,
//传入的el是任意的元素,type是事件的类型,fn是事件处理函数,
//arg是addEventListener()的第3个参数,不传,默认为false
function myaddEventListener(el, type, fn, arg) {
if (arg == undefined) {
arg = false;
};
//判断浏览器是否支持这个方法
if (el.addEventListener) {
el.addEventListener(type, fn, arg);
console.log("支持addEventListener");
} else if (el.attachEvent) {
el.attachEvent("on" + type, fn);
console.log("支持attachEvent");
} else {
el["on" + type] = fn;
console.log("addEventListener和attachEvent都不支持");
};
};
//测试
myaddEventListener(document.getElementById("btn"), "click", function () {
console.log("jzx");
});
myaddEventListener(document.getElementById("btn"), "click", function () {
console.log("phm");
});
myaddEventListener(document.getElementById("btn"), "click", function () {
console.log("gloria");
});
</script>
谷歌浏览器中运行结果
事件的解绑
元素.on 事件名字=null
行内式绑定和元素属性绑定的解绑,直接将属性值置空。
<div class="box2">
<button class="btn2">方式2</button>
</div>
<script>
let btn=document.querySelector(".btn2");
btn.onclick=()=>{
btn.onclick=null;
console.log("同类型事件会后者覆盖了前者");
};
</script>
点击事件触发后先将元素.on 事件名字的属性值设为空,这样点击事件只会触发1次,除非再次刷新页面可再次触发1次。
<div class="box1">
<button class="btn1" onclick="test();fn()">方式1</button>
</div>
<script>
function test(){
console.log("test函数执行成功");
};
function fn(){
console.log("fn函数执行成功");
};
let btn=document.querySelector(".btn1");
btn.onclick=null;
</script>
行内式同理,置空后当点击按钮时没有任何反应。
元素.removeEventListener()
需要移除什么元素的事件就用什么元素调用removeEventListener()。解绑事件的时候,需要在绑定事件的时候,使用命名函数,解绑的时候使用函数名。
参数
第1个参数:事件类型名称,没有on。
第2个参数:函数名,要和 addEventListener 指向同一个函数才能解绑成功。
第3个参数也是布尔值。
<div class="box3">
<button class="btn3">btn1</button>
<button class="btn">btn2</button>
</div>
<script>
let btn=document.querySelector(".btn3");
let btn1=document.querySelector(".btn");
let fg=()=>{
console.log("gloria");
};
btn.addEventListener("click",fg);
let fn=()=>{
btn.removeEventListener("click",fg)
console.log("第一个按钮点击事件解绑成功");
};
btn1.addEventListener("click",fn);
</script>
元素.detachEvent()
用attachEvent绑定用元素.detachEvent(“on事件类型”,函数名字);(IE)
解决兼容问题的解绑
//为任意的一个元素,解绑对应的事件
function myremoveEventListener(el, type, fnName, arg) {
if (arg == undefined) {
arg = false;
};
if (el.removeEventListener) {
el.removeEventListener(type, fnName, arg);
} else if (el.detachEvent) {
el.detachEvent("on" + type, fnName);
} else {
el["on" + type] = null;
};
};