事件监听
在编程时系统内发生的动作或者发生的事情。比如:用户在网页上单击一个按钮
让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应
也称为"绑定事件或者注册事件" (比如:点击按钮可以切换图片)
事件源:某个DOM元素触发了事件
事件类型:用什么方式触发(比如:鼠标单击click、鼠标经过mouseover等)
事件调用的函数:要做什么事情
元素对象.addEventListener('事件类型', 要执行的函数)
< body>
< button> 点击</ button>
< script>
const btn = document. querySelector ( 'button' )
btn. addEventListener ( 'click' , function ( ) {
alert ( 'Hello World' )
} )
</ script>
</ body>
两种注册事件的区别
传统 on 注册
同一个对象,后面注册的事件会覆盖前面注册(同一个事件) 直接使用 null 覆盖就可以实现事件的解绑 都是冒泡阶段执行的
事件监听注册
后面注册的事情不会覆盖到前面注册的事件 可以通过第三个参数去确定是在冒泡或者捕获阶段执行 必须使用 removeEventListener(事件类型,事件处理函数,获取捕获或者冒泡阶段) 进行事件的解绑操作 匿名函数无法被解绑
事件类型
鼠标事件
click 鼠标点击 mouseenter 鼠标进入 mouseleave 鼠标离开
焦点事件
键盘事件
文本事件
具体演示
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< title> Document</ title>
< style>
div {
width : 200px;
height : 200px;
background-color : pink;
}
</ style>
</ head>
< body>
< div> </ div>
< script>
const div = document. querySelector ( 'div' )
div. addEventListener ( 'mouseenter' , function ( ) {
div. style. backgroundColor = 'green'
} )
div. addEventListener ( 'mouseleave' , function ( ) {
div. style. backgroundColor = 'red'
} )
</ script>
</ body>
<body>
<span>请输入</span>
<input type="text">
<script>
const span = document.querySelector('span')
const input = document.querySelector('input')
input.addEventListener('focus', function () {
span.style.color = 'red'
span.innerText = '输入中'
})
input.addEventListener('blur', function () {
span.style.color = 'green'
span.innerText = '已完成'
})
</script>
</body>
<div>
键盘当前状态:
<span>弹起</span>
</div>
<input type="text">
<script>
const span = document.querySelector('span')
const input = document.querySelector('input')
input.addEventListener('keydown', function () {
span.style.color = 'red'
span.innerText = '按下'
})
input.addEventListener('keyup', function () {
span.style.color = 'green'
span.innerText = '弹起'
})
</script>
< body>
< input type = " text" >
< div>
当前输入: < span> </ span>
</ div>
< script>
const input = document. querySelector ( 'input' )
const span = document. querySelector ( 'span' )
input. addEventListener ( 'input' , function ( ) {
span. style. color = 'red'
span. innerHTML = input. value
} )
</ script>
</ body>
事件对象
基本概念
事件对象是什么?
它是一个对象,这个对象里有事情触发时的相关信息
例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置的信息
使用场景:
可以判断用户按下了哪个键,比如:按下回车键可以发布新闻
可以判断鼠标点击了哪个元素,从而做出相应操作
事件对象在哪里?
事件绑定的回调函数的第一个参数
具体演示
< body>
< input type = " text" >
< script>
const input = document. querySelector ( 'input' )
input. addEventListener ( 'keyup' , function ( event ) {
if ( event. key === 'Enter' ) {
console. log ( '成功按下了回车键' )
}
} )
</ script>
</ body>
环境对象
环境对象,指的是函数内部特殊的变量 this,它代表着当前函数运行时所处的环境
(粗略判断规则:谁调用,this 就是谁)
< body>
< button> 点击</ button>
< script>
const btn = document. querySelector ( 'button' )
btn. addEventListener ( 'click' , function ( ) {
this . style. color = 'red'
} )
</ script>
</ body>
回调函数
概念:如果将函数A做为参数,传递给函数B,我们称函数A为回调函数
事件流
基本概念
事件流:指的是事件完整执行过程中的流动路径 捕获阶段:Document =》Element html =》Element body =》Element div 冒泡阶段:Element div =》Element body =》Element html =》Document
语法:
元素.addEventListener(事件类型, 事件处理函数, 是否使用捕获机制)
注意:
addEventListener第三个参数传入true:代表是捕获阶段(很少使用)
addEventListener第三个参数传入false或者不写:代表是冒泡阶段
捕获
< body>
< div class = " father" >
< div class = " son" >
点我
</ div>
</ div>
< script>
const father = document. querySelector ( '.father' )
const son = document. querySelector ( '.son' )
document. addEventListener ( 'click' , function ( ) {
alert ( 'I am grandfather' )
} , true )
father. addEventListener ( 'click' , function ( ) {
alert ( 'I am father' )
} , true )
son. addEventListener ( 'click' , function ( ) {
alert ( 'I am son' )
} , true )
</ script>
</ body>
当鼠标点击"点我"时候,弹出框弹出的先后顺序是:
I am grandfather
I am father
I am son
冒泡
< body>
< div class = " father" >
< div class = " son" >
点我
</ div>
</ div>
< script>
const father = document. querySelector ( '.father' )
const son = document. querySelector ( '.son' )
document. addEventListener ( 'click' , function ( ) {
alert ( 'I am grandfather' )
} , false )
father. addEventListener ( 'click' , function ( ) {
alert ( 'I am father' )
} , false )
son. addEventListener ( 'click' , function ( ) {
alert ( 'I am son' )
} , false )
</ script>
</ body>
当鼠标点击"点我"时候,弹出框弹出的先后顺序是:
I am son
I am father
I am grandfather
阻止冒泡
问题:
因为默认就有冒泡模式的存在,所以容易导致事情影响到父级元素
需求:
若想把事情就限制在当前元素内,就需要阻止事件冒泡
语法:
事件对象.stopPropagation()
注意:
此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效
< body>
< div class = " father" >
< div class = " son" >
点我
</ div>
</ div>
< script>
const father = document. querySelector ( '.father' )
const son = document. querySelector ( '.son' )
document. addEventListener ( 'click' , function ( ) {
alert ( 'I am grandfather' )
} , false )
father. addEventListener ( 'click' , function ( ) {
alert ( 'I am father' )
} , false )
son. addEventListener ( 'click' , function ( event ) {
alert ( 'I am son' )
event. stopPropagation ( )
} , false )
</ script>
</ body>
事件解绑
< body>
< button> 确认</ button>
< script>
const btn = document. querySelector ( 'button' )
btn. onclick = function ( ) {
alert ( '用户点击了确认' )
btn. onclick = null
}
</ script>
</ body>
<body>
<button>确认</button>
<script>
const btn = document.querySelector('button')
// 匿名函数无法解绑
function judge() {
alert('用户点击了确认')
}
btn.addEventListener('click', judge)
btn.removeEventListener('click', judge)
</script>
</body>
事件委托
基本理解
情景带入
需求:
要求点击某个li,那个li就变成红色。
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
解决办法:
方式一:给每个li都添加一个事件(太麻烦)
方式二:使用事件委托,将事件委托给ul进行处理
事件委托的优点 :减少注册事件的次数,可以提供程序性能
事件委托的原理 :利用事件冒泡的特点(给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件)
具体演示
< body>
< ul>
< li> li-1</ li>
< li> li-2</ li>
< li> li-3</ li>
< li> li-4</ li>
< li> li-5</ li>
< p> 我是p标签</ p>
</ ul>
< script>
const ul = document. querySelector ( 'ul' )
ul. addEventListener ( 'click' , function ( event ) {
if ( event. target. tagName === 'LI' ) {
event. target. style. color = 'red'
}
} )
</ script>
</ body>
阻止默认行为
< body>
< form action = " https://www.baidu.com" >
< input type = " submit" value = " 免费注册" >
</ form>
< script>
const form = document. querySelector ( 'form' )
form. addEventListener ( 'submit' , function ( event ) {
event. preventDefault ( )
} )
</ script>
</ body>
<body>
<a href="">点击跳转</a>
<script>
const a = document.querySelector('a')
a.addEventListener('click', function (event) {
// 阻止默认行为,此处的默认行为是"跳转"
event.preventDefault()
})
</script>
</body>
其他事件
页面加载事件
作用:
可以控制:先加载外部资源(如:图片、CSS、JS等)加载完毕时触发的事件
意义:
1.有些时候,我们需要等页面所有资源全部加载完了,再做一些事情
2.一些老项目的代码,往往把 script 写在 head 中
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< title> Document</ title>
< script>
window. addEventListener ( 'load' , function ( ) {
} )
</ script>
</ head>
注意:load 不仅可以监听整个页面资源加载完成,也可以针对某个资源绑定 load 事件
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< title> Document</ title>
< script>
img. addEventListener ( 'load' , function ( ) {
} )
</ script>
</ head>
当初始的 HTML 文档被完全加载和解析完成后,DOMContentLoaded 事件被触发,而无需等待CSS样式表、图像等完全加载(此方法更快加载事件)
// 监听页面 DOM 加载完毕
document.addEventListener('DOMContentLoaded', function () {
// ......
})
页面滚动事件
基本认识
含义:
滚动条在滚动的时候持续触发的事件
意义:
很多网页需要检测用户把页面滚动到某个区域后做一些处理,比如固定导航栏、返回顶部
监听滚动
< body>
< div style = " height : 2000px; " > </ div>
< script>
window. addEventListener ( 'scroll' , function ( ) {
console. log ( '我滚动了' ) ;
} )
</ script>
</ body>
< body>
< div style = " width : 50px; height : 150px; overflow : scroll; " >
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
</ div>
< script>
const div = document. querySelector ( 'div' )
div. addEventListener ( 'scroll' , function ( ) {
console. log ( '我滚动了' ) ;
} )
</ script>
</ body>
获取位置
属性:
scrollLeft 和 scrollTop
作用:
获取元素内容往左、往上滚动出去的距离
注意:
1.此属性既可以读取当前距离,也可以给它进行距离的赋值!
2.本文只通过两个"向上滚动的距离"进行演示
< body>
< div style = " width : 50px; height : 150px; overflow : scroll; " >
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
</ div>
< script>
const div = document. querySelector ( 'div' )
div. addEventListener ( 'scroll' , function ( ) {
console. log ( div. scrollTop) ;
} )
</ script>
</ body>
< body>
< div style = " height : 2000px; " > </ div>
< script>
window. addEventListener ( 'scroll' , function ( ) {
console. log ( document. documentElement. scrollTop) ;
} )
</ script>
</ body>
跳转到窗口的某个滚动距离:
方法一:利用 scrollTop 的可赋值性,document.documentElement.scrollTop = 100px
方法二:windows.scrollTO(x, y)
页面尺寸事件
< body>
< script>
window. addEventListener ( 'resize' , function ( ) {
console. log ( "窗口尺寸改变了!" ) ;
} )
</ script>
</ body>
注意:
通过获取元素的可见部分宽高,不包含边框,margin,滚动条
属性:
clientWidth 和 clientHeight
< body>
< div style = " display : inline-block; " >
随着内容的变化,span标签的宽度也随之变化
</ div>
< script>
const div = document. querySelector ( 'div' )
console. log ( div. clientWidth) ;
</ script>
</ body>
元素的尺寸与位置
获取宽高
介绍:
1.获取元素的自身宽高、包含元素自身设置的宽高、padding、border
2.获取出来的是数值,方便计算
属性:
offsetWidth 和 offsetHeight
注意:
获取的是可视宽高,如果盒子是隐藏的,获取的结果是0
< body>
< div style = " width : 100px; height : 100px; background-color : pink; margin : 100px auto; " > </ div>
< script>
const div = document. querySelector ( 'div' )
console. log ( div. offsetWidth) ;
console. log ( div. offsetHeight) ;
</ script>
</ body>
获取位置
介绍:
获取元素距离自己"有定位的"父级元素的左、上距离
属性:
offsetLeft 和 offsetTop
注意:
这两个属性是只读属性,不能赋值。
< body>
< div style = " width : 100px; height : 100px; background-color : pink; margin : 100px auto; " > </ div>
< script>
const div = document. querySelector ( 'div' )
console. log ( div. offsetTop) ;
console. log ( div. offsetLeft) ;
</ script>
</ body>
速查(属性总结)
属性 作用 说明 scrollLeft 和 scrollTop 被卷去的头部和左侧 配合页面滚动使用(可读写) clientWidth 和 clientHeight 获得元素宽度和高度 不包含border、margin、滚动条,用于js获取元素大小(只读属性) offsetWidth 和 offsetHeight 获取元素宽度和高度 包含border、padding,滚动条等(只读属性) offsetLeft 和 offsetTop 获取元素距离自己定位父级元素的左、上距离 在获取元素定位的时候使用(只读属性)