事件
事件的概念
要完成事件编程需要满足三部分要求:
- 事件源:指定事件的源对象,找到某个绑定事件的元素
- 事件函数(完成业务),绑定事件过后,执行的业务逻辑。
- 事件对象:在触发这个时间的时候,给你默认封装一个对象,这个对象里面包含的执行事件的一些信息。
js基于事件驱动的一种编程方式,事件一直都有,只是你没有监听这个时间,开发中需要完成某个事件的业务操作,我们就需要在事件源里面绑定一个事件(监听这个动作)—触发我们的事件函数,传递一个event对象
const odiv = document.getElementById("odiv")
//event就代表事件对象主要发生事件绑定,默认都会创建一个这样的对象
odiv.onclick = function(event){
}
事件函数要执行成功,必须完成绑定的操作。
事件的分类
事件类型的分类主要按照功能来划分:
*事件类型名* | *描述* |
---|---|
UI事件 | 用户与网页元素之间的交互,不一定是用户触发 |
焦点事件 | 当页面元素获得焦点或失去焦点 |
鼠标事件 | 当使用鼠标时的事件 |
滚轮事件 | 当使用鼠标滚轮时触发 |
文本事件 | 当在框里输入文本时触发 |
键盘事件 | 用户通过键盘与页面交互时触发 |
变动事件 | 当dom树结构发生变化时 |
Touch事件 | 针对触摸屏幕的事件 |
ui事件
load才是事件的名字,onload绑定事件
-
onload()代表页面DOM渲染完毕后就会执行这个事件指定的代码
window.onload = function () { // 代码自上而下的运行,当执行到js代码获取dom节点,dom都还没加载完成 const box = document.getElementsByClassName("box")[0]; console.log(box); }
一般用于等页面加载完毕后在执行js代码。
-
onunload()等页面推出关闭卸载的时候执行这个事件
window.onunload = function(){ alert(123); }
使用这个时间可以完成页面卸载的时候对资源进行回收。
-
onresize()监听到窗口发生变化
window.onresize = function(){ // 获取到屏幕可用区域的宽和高 console.log(document.documentElement.clientWidth); console.log(document.documentElement.clientHeight); console.log(document.body); }
焦点事件
- onfoucs()获取焦点
- onblur()失去焦点
- foucsin() 目前这个事件在IE下面可以正常运行,在chrome里面无法使用
- foucsout()
鼠标事件
- onclick():鼠标点击事件
- ondblclick():鼠标双击事件,要求在指定时间间隔里面要完成两次点击才算双击
- onmouseenter():当鼠标移入到事件源的时候触发
- onmouseover():鼠标进入到事件源里
- onmouseleave():当鼠标离开事件元素的时候
- onmousedown():当鼠标按下的时候
- onmouseup():当鼠标弹起来的时候
- onmousemove():鼠标在事件源里面移动的时候
- onmousewheel():当个滚轮的时候,触发
键盘事件
- onkeydown()键盘按钮的时候触发
- onkeypress()按下键盘,释放键盘的一瞬间。按过
- onkeyup()松开键盘,弹起来
执行顺序 down-press-up
变动事件
onchange()这个事件主要就是检测选项是否发生改变。
滚动事件
onscroll()这个事件称为滚动事件。监听指定元素是否有滚动
表单事件
-
onsubmit() 提交submit按钮触发,绑定给表单
-
onreset(),点击reset按钮的触发,绑定给表单
JS事件的使用方案
DOM0级:绑定事件主要就是通过on关键字来绑定事件 onclick onchange
-
动态绑定:获取到这个节点后,在js中绑定事件
-
静态绑定:直接在标签上面加上时间绑定。指定要执行事件函数
//动态绑定 var obtn = document.getElementById("btn"); obtn.onclick = function(){ } //静态绑定 <button type=“button” onclick="check()">提交</button> function check(){ }
优点:静态绑定的优点,可以在定义标签的时候,就设计事件,并且还能根据自己的需求传递到函数里面使用
缺点:代码可读性差,js和html混合在一起,不利于维护。
DOM2级:
专门提供了API来绑定我们事件。
var obtn = document.getElementById("btn")
obtn.addEventListener("click",function(){},true/flase);
addEventListener就是DOM级里面提出来的一种绑定方式。这种方式因为出现的比较晚,老版本浏览器会有兼容问题。
Event事件对象
event对象特点
有事件任务执行,事件源、事件函数、事件对象、事件函数必须绑定到事件源
只要有事件的绑定,系统会默认产生一个事件对象。Event对象
event包含执行事件的产生的一些状态,鼠标的坐标、键盘按下的键、执行哪个事件。。
执行不同的事件,event对象里面内容可能产生差异。
const oinp = document.getElementById("inp")
//event名字可以随便取,看成是形参,由事件来调用这个函数
oinp.onclick = function(event){
}
oinp.onkeyup = function(event){
}
event里面坐标
* offsetX:当前你点击的事件源这个对象内部的坐标,点击的位置相对于事件源的位置。偏移量
* offsetY:
*clientX-clientY 你触发事件的时候你鼠标的位置相对于浏览器可视区域的 水平-垂直距离。
* pageX-pageY:你触发事件的时候你的鼠标的位置相对于浏览器的水平和垂直距离,包含滚动条的距离
* screenX,screeY:你触发事件的时候鼠标的位置相对于(屏幕的位置)
* xy相对父元素的位置
event可以解决问题
基于event target可以完成事件委托。
事件流
在网页中执行一个操作可能会触发多个事件的执行,并且这些事件在执行的时候会按照一定的顺序来进行执行。
官方:事件流就是页面上接受事件的顺序。
在页面上嵌套的多个元素都有相同的事件,那点击元素的时候,到底应该从内往外触发事件还是从外网内触发事件,这个问题是早期各个浏览器标准不同的问题。
对于IE浏览器:从内往外,先子元素在父元素---- 事件冒泡
对于chrome、ff:从外往内:先父元素在子元素---- 事件捕获
事件冒泡
const oa = document.getElementById("oa");
const box = document.getElementById("box");
oa.onclick = function(){
alert("点击了a标签");
}
box.onclick = function(){
alert("点击了box");
}
document.body.onclick = function(){
alert("点击了body");
}
事件的冒泡就是从最具体的元素开始,逐级向上一层一层的触发事件,直到传递到最外层元素已经执行完了。冒泡结束。
冒泡排序:从小到大的顺序来排序。
事件捕获
对于大部分浏览器来说,默认支持的都是事件捕获.
W3C为了将两种方案都作为标准,冒泡和捕获目前都是标准规范,现代浏览器默认都会支持冒泡和捕获。
使用哪种方式来执行你的事件,需要你在代码中自己规定。传统的事件绑定并不能指定时间是冒泡还是捕获、必须用现在指派。DOM2级中提供的方案。
DOM2级的事件处理程序来完成捕获设置
const box = document.geteElementById("box");
//第一个参数 事件的名称 第二个参数事件函数 第三个参数 布尔 控制冒泡(false)和捕获(true)
box.addEventListener("click",function(){},boolean)
在Chrome和FF safira等等浏览器下面,冒泡和捕获都存在,先捕获完成,在冒泡出去。
事件绑定的语法
学习DOM2级事件一下几个api:
- addEventListener()
- removeEventListener()
这两个api在IE9以上的版本才能使用。IE8完全不支持。
在IE8下面有自己的绑定事件API
- attachEvent()
- detachEvent()
传统绑定–DOM0级 现代绑定 DOM2级 。根据自己的需求两种方式都可以。传统没有兼容问题。
默认事件和阻止冒泡
在页面上某个标签或者某些操作默认产生事件。
a标签:你点击a标签过后默认就会跳转。
<a href="#" onclick="del()">删除</a>
在a标签里面我们有默认事件完成跳转,你可以制止这个阻止
submit按钮有默认事件,你点击了submit按钮就会默认跳转。以form表单的路径作为跳转。
<form>
<button type="submit"></button>
</form>
阻止超链接跳转:
- 使用伪链接
javascript:void(0)
点击超链接过后,执行伪链接。void(0)空函数是javascript提供的一个函数。 - 使用伪链接
javascript:;
- 使用事件对象event来完成事件阻止提交
event.preventDefault();
表单提交默认事件:
1. 可以在submit事件里面return false 组织表单的提交。阻止了默认事件
2. 可以使用` event.preventDefault();`代码来组织提交。
冒泡是浏览器的默认行为,在开发中有时候不想要默认的冒泡,这个需要阻止这个冒泡行为
event.stopPropagation()
事件委托
在页面上有了事件提高了用户交互体验,如果有很多动态交互那我们需要创建很多的事件。不管代码层面的冗余还在内存的I一个消耗都对网页的效率有影响。
事件委托概念:事件委托并不是一项新技术,就是一种处理页面事件程序的一种方案。这种方式就是利用冒泡机制来完成对页面上某一类事件的统一处理。
event对象在冒泡里面是会一直传递给父元素。就可以在父元素的事件函数里面获取到子元素event这样就可以取出到底是哪个子元素,根据结果来执行不同的业务。
document.body.addEventListener("click", function (event) {
console.log(event.target);
switch (event.target.getAttribute("name")) {
case "button1":
(function () {
console.log("button1");
})();
break;
case "button2":
(function () {
console.log("button2");
})();
break;
case "button3":
(function () {
console.log("button3");
})();
break;
}
}, false)
好处:
- 减少重复事件绑定过程。让父元素绑定一次。
- 减少DOM的操作次数,每次事件绑定都会操作DOM
- 减少函数的创建次数,节约了内存空间
- 统一分发,统一管理事件。
代码的优化
<form id="myform">
<input type="button" value="按钮1" name="button1">
</form>
<script>
const oinp = document.getElementByTagName("input")
const omyform = document.getElementById("myform")
oinp.onclick = function(){
//业务
//数据验证和提交
//按钮删除
this.onclick = null; //接触函数和按钮的绑定关系
omyform.removeChild(this);
}
</script>
在老版本浏览器里面IE8以及一下,会出现节点已经删除了,但是绑定的事件还存在,导致内存泄露(一直没用的函数变量无法被回收)。消耗资源。目前新版本的浏览器已经做了优化。
同一个事件可以重复绑定吗?
<form id="myform">
<input type="button" value="按钮1" name="button1">
</form>
<script>
const oinp = document.getElementByTagName("input")
const omyform = document.getElementById("myform")
oinp.onclick = function(){
log(123)
}
oinp.onclick = function(){
log(345)
}
</script>