目录
1.定义
事件是指在用户或浏览器自身执行的某种动作,响应这些动作的代码称为事件处理程序。
JavaScript 通过事件驱动模型允许你为特定事件设置处理函数,当这些事件发生时,相应的处理函数就会被触发执行。
2.事件组成
事件由三部分组成
- 事件源:给某元素绑定事件,该元素被称为事件源;
- 事件类型:如点击事件click;
- 事件处理程序:handler
3.注册/移除事件
[1]注册事件
注册事件有两种方式,一种是使用on关键字来进行事件注册,另一种是通过addEventListener方法进行事件注册。
(1)on关键字
[1]行内式
<element onxxx='执行代码'><element>
<!-- 该div元素点击时会在控制台打印111-->
<div onclick='console.log(111)'>点击打印<div>
<!-- 行内式绑定的是执行代码, 若是绑定方法需要设置为方法的调用!!! -->
<div onclick='toCon()'>点击打印<div>
<script>
function toCon(){
console.log(111)
}
</script>
[2]通过属性绑定的方式注册事件
element.onxxx = function(){...}
const box = document.querySelector('div')
box.onclick = function(){
console.log(111)
}
使用on关键字注册事件的特点是 如果同一个元素,拥有多个相同事件,如果利用on关键字,那么后面的事件会覆盖前面的事件--->也就是说若是使用on关键字注册事件,同一元素不能注册相同的事件!
box.onclick = function () {
console.log('大家好,我是班长');
}
box.onclick = function () {
console.log('大家好,我是课代表');
}
(2)使用addEventListener来注册事件
使用addEventListener注册事件,可以实现给一个元素,设置多个相同的事件
(1)语法
addEventListener(事件类型,事件方法,true/false)
第三个参数为false那么该事件为冒泡事件,若是为true那么该事件为捕获事件
- eg注册点击事件
-
function fun1() { console.log('大家好,我是班长'); } addEventListener('click' fun1,false)
[2]移除事件
(1)on关键字注册的事件在移除时直接置空;
// 1. 利用on设置事件
box.onclick = function () {
console.log('我只能打印一次');
// 点击完之后立刻清空点击事件
this.onclick = null;
}
(2)addEventListener注册事件使用removeEventListener方法移除事件
function fun() {
console.log('我只能打印一次');
// 点击完之后移除事件
// removeEventListener()
// add怎么赋值,remove就怎么赋值
box.removeEventListener('click',fun,false)
}
4.事件对象
当事件发生时,浏览器会创建一个事件对象,并将其作为参数传递给事件处理函数。这个对象包含了有关事件的详细信息,例如事件类型、目标元素等。
注意:若是行内式给元素绑定事件时,若是绑定的是方法的调用,需要手动将事件对象event传入,否则获取不到事件对象。
<a href="https://www.baidu.com/" onclick="bandA()">跳转到百度</a>
<script>
function bandA(e){
console.log(e) // undefined
}
</script>
<a href="https://www.baidu.com/" onclick="bandA(e)">跳转到百度</a>
<script>
function bandA(e){
console.log(e) // undefined
}
</script>
<a href="https://www.baidu.com/" onclick="bandA(event)">跳转到百度</a>
<script>
function bandA(e){
console.log(e) // 事件对象
}
</script>
[1]获取该事件的事件类型
e.type
[2]获取引用触发事件的 DOM 元素
- 事件处理函数中的this指向事件源(绑定事件的元素)
- 事件对象中存在一个target属性指向被点击的元素
-
e.target
-
[3]阻止事件的默认行为
e.preventDefault();
示例
<!-- 当点击下述a标签时会跳转到百度首页 -->
<a href="https://www.baidu.com/">跳转到百度</a>
<!-- 若是不想跳转,可以阻止a标签的默认行为来阻止a标签跳转 -->
<a href="https://www.baidu.com/" onclick="bandA(event)">跳转到百度</a>
<script>
function bandA(e){
e.preventDefault()
}
</script>
[4]阻止事件冒泡/捕获
e.stopPropagation();
5.事件类型
注:事件不采用驼峰命名,都是用小写
1)表单元素的事件
表单元素常用的事件如下:
-
[1]表单元素值改变事件: input;
-
[2]input元素值选中事件:select
-
[3]获得焦点事件--主要用于表单:foucs
-
[4]失去焦点事件:blur
-
[5]表单被重置:reset
-
[6]表单被提交:submit
-
[7]值改变事件:change
-
单选框选择某一项时触发。复选框选择某一项时触发。下拉列表选择某一项时触发
-
-
[8]点击事件:click
示例1:当输入框中内容改变的时候,打印输入框中的内容;
<body>
<input type="text" id="input" />
<script>
let inputBox = document.getElementById('input')
inputBox.oninput = function () {
console.log(inputBox.value)
}
</script>
</body>
示例2:当输入框获取焦点时,选中输入框中的所有内容
<input type="text" placeholder="百度一下">
<script>
const searchBox = document.querySelector('input')
searchBox.onfocus = function(){
if (!searchBox.value){
searchBox.value = searchBox.placeholder
}
searchBox.select()
}
</script>
2)鼠标事件
- [1]鼠标点击事件 :click
- [2]鼠标双击事件:dblclick
- [3]鼠标移入时触发:mouseenter
- 当鼠标指针进入元素时触发
- mouseover也是当鼠标指针进入元素时触发,与mouseenter的区别是mouseenter不会冒泡,mouseover会冒泡 => 它也会在子元素上触发
- [4]鼠标移出时触发:mouseleave
- 当鼠标指针离开元素时触发
- mouseout也是当鼠标指针离开元素时触发,与mouseleave的区别是mouseleave不会冒泡,mouseout会冒泡 => 它也会在子元素上触发
- [5]鼠标移动事件:mousemove
- 当鼠标指针在元素内移动时持续触发 => 是一个持续触发得过程(考虑性能问题)
- [6]鼠标按下事件:mousedown
- [7]鼠标弹起事件:mouseup
- [8]鼠标尝试打开右菜单:contextmenu
鼠标事件中事件对象的属性
- clientX/clientY: 相对于浏览器窗口左上角的鼠标指针的X和Y的坐标
- pageX/pageY: 相对于页面左上角的鼠标指针的X和Y的坐标
示例1: 鼠标移入文本放大展示
<style>
div{
width: 200px;
height: 100px;
border:1px solid #666;
}
.display-font{
font-size: 20px;
}
</style>
<div onmouseenter="changeSize(event,1)" onmouseleave="changeSize(event, 2)" >详细说明</div>
<script>
function changeSize(e, type){
const box = document.querySelector('div')
switch(type){
case 1:
box.setAttribute('class', 'display-font')
break
case 2:
box.removeAttribute('class')
}
}
</script>
示例2: 禁止打开右侧菜单
<div>
<p>我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。</p>
</div>
<script>
const pBox = document.querySelector('p')
pBox.oncontextmenu = function(e){
// 取消事件的默认行为
e.preventDefault()
}
</script>
3)键盘事件
- [1]键盘按下时触发:onkeydown
- 当用户按下任意键时立即触发
- 如果按住某个键不放,
keydown
会持续触发(取决于键盘的重复速率设置)
- [2]键盘弹起时触发: onkeyup
- 当用户释放按键时触发
- 每次按键只触发一次,即使用户长时间按住某个键也不会重复触发
键盘事件中事件对象的属性
[1]key:返回被按下的键的实际值
document.addEventListener('keydown', function(e){
console.log(e.key) // 按下a键则打印a,按下左箭头则打印ArrowLeft
}, false)
[2]code:表示物理按键的位置,不受键盘布局影响。
[3]keycode:返回触发事件的键的 ASCII 值(已被废弃,还支持)
[4]ctrlKey/shiftKey/altKey/metaKey: 布尔值,判断是否同时按下 Ctrl
, Shift
, Alt
, 或 (
Windows 键或 Mac 上的 Command 键)
[5]repeat:对于 keydown
事件,如果一个键被持续按下,则该属性为 true
,可用于区分长按和短按
示例1: 京东搜索框案例
打开京东首页,当点击“s”键时搜索框会自动聚焦。
<input type="text" placeholder="请输入">
<script>
document.addEventListener('keyup', function(e){
console.log('e.key',e.key)
if(e.key === 's') {
// 聚焦搜索框
const searchBox = document.querySelector('input')
searchBox.focus()
}
}, false)
在此需要监听keyup事件,若是监听keydown事件 => 在键盘按下的时候就会聚焦,那么s相当于输入到input框中了。
示例2: 通过上下左右箭头控制元素移动
在很多游戏中,会通过上下左右箭头控制人物进行移动,其实就是通过监听键盘按下事件实现的。
<style>
.screen{
width: 300px;
height: 600px;
border: 1px solid #666;
padding: 50px;
position: relative;
}
.person{
width: 30px;
height: 30px;
background-color: red;
position: absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
}
</style>
<div class="screen">
<div class="person"></div>
</div>
<script>
const person = document.querySelector('.person')
let topL = parseInt(window.getComputedStyle(person).top)
let leftL = parseInt(window.getComputedStyle(person).left)
document.onkeydown = function(e){
switch(e.key){
case 'ArrowUp':
if(topL >= 25){
topL = topL - 10
} else if(topL<25 && topL>15) {
topL = 15
}
break
case 'ArrowDown':
// 边界值top+15 = 700
if(topL <= 675){
topL += 10
} else if(topL>675 && topL<685) {
topL = 685
}
break
case 'ArrowLeft':
// left-15 = 0
if(leftL >= 25){
leftL = leftL - 10
} else if(leftL<25 && leftL>15) {
leftL = 15
}
break
case 'ArrowRight':
if(leftL <= 375){
leftL += 10
} else if(leftL>375 && leftL<385) {
leftL = 385
}
break
}
person.style.left = leftL + 'px'
person.style.top = topL + 'px'
}
</script>
4)盒子拖拽事件(html5新增)
- [1]盒子拖拽事件
- 1)开始拖拽:ondragstart
- 2)拖拽过程中:ondrag
- 3)结束拖拽:ondragend
- [2]容器拖拽事件
- 1)具有拖拽元素进入容器:ondragenter
- 2)具有拖拽元素的盒子在容器中移动:ondragover
- 3)具有拖拽元素的盒子离开容器:ondragleave
- 4)具有拖拽元素的盒子进入容器后松手:ondrop
- 注:执行4事件必须禁止2事件的默认效果;
5)视频音频事件
- [1]视频/音频的开始播放事件:onplay
- [2]音频/视频的暂停播放事件:onpause
6)值改变事件
- 值改变:onchange
- input标签值改变:oninput
7)窗口事件
- load:当整个页面(包括所有的资源:图片、样式表等)加载完成时触发。
- unload:当用户退出页面时触发(现在较少使用,更多地转向
beforeunload
来提示用户保存未保存的工作)。 - beforeunload:在即将卸载页面之前触发,允许显示一个确认对话框询问用户是否真的要离开。
- resize:当浏览器窗口大小改变时触发。
- scroll:当用户滚动页面或元素时触发。
8)复制事件
- copy:当用户点击复制时触发
- 注:若是禁止该事件的默认行为,虽然复制还是可以点击,但是内容并不会被复制成功
- selectstart:当用户开始选择(选中)页面上的内容时触发的事件
示例1: 当用户想要复制页面内容时,提示开通会员再复制
<p>我是一个兵 来自老百姓111</p>
<script>
const isMember = 0 // 模拟后端数据非会员
document.addEventListener('selectstart', function(e){
if (!isMember){
alert('请先开通会员再来复制吧~')
e.preventDefault()
}
}, false)
</script>
6.事件阶段
事件分为三大阶段
- 捕获事件
- 当某个事件被触发之后,那么它所有的 父元素 相同的事件 也会被触发;
- 执行顺序:在捕获的过程中,最外层(根)元素的事件先被触发,然后依次向内执行,直到触发最里面的元素(事件源)--->由外到内,由父到子;
- 目标事件(正常事件)
- 冒泡事件
- 当某个元素的事件被触发之后,那么它所有的 父元素 相同的事件 也会被触发;
- 执行顺序:由内到外,从小到大;
执行顺序
从上往下开始执行;
- 先执行捕获阶段;
- 再执行目标阶段;
- 再执行冒泡阶段
[1]什么事件为冒泡事件;什么事件是捕获事件
- 使用on注册的事件是冒泡事件;
- 使用addEventListener注册的事件
- 若是第三个参数为false则是冒泡事件;
- 若是第三个参数为true若是捕获事件;
[2]阻止事件冒泡/事件捕获
- 即可以阻止事件冒泡又可以阻止事件捕获
- e.stopPropagation();
- 阻止事件冒泡
- e.cancelBubble();
7.如何理解事件代理
[1]定义:事件代理简单来说就是:事件不直接绑定在某个元素上而是绑定在该元素的父元素上,进行触发的时候再通过条件进行判断;
[2]优点:
- 大量节省内存占用,减少注册事件;
- 当在新增加子对象时,无需再对齐进性事件绑定,对于动态内容比较友好;
[3]举例说明
如下,若是我们为li设置点击事件,需要循环设置10个点击事件(但是若是li元素有成千上百个呢,直接为li元素设置点击事件就不太友好了),事件代理仅需设置一个点击事件就可以完成所需功能!
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
<script>
let ul = document.getElementById('ul')
ul.onclick=function(e){
console.log(e.target.innerHTML);
}
</script>