事件
概述
事件是指代一个东西的操作被另外一个东西进行监听后的一个过程,这个过程可以完成对应的操作(处理函数)。事件监听是一个标准的观察者模式(observer)也被称为发布、订阅者模式。事件是一个异步机制。他相当于一个 执行者执行 -- 观察者观察 --- 处理函数执行 这个流程称为事件。
事件的组成
- 事件名 (内置的)
- 执行对象 (元素对象)
- 处理函数 (自定义函数)
- 观察者 (js的事件引擎)
示例
点击按钮触发一个操作改变按钮的颜色
事件名 点击
执行对象 按钮
处理对象 js引擎
处理函数 改变按钮的颜色
事件的模式
内联模式(嵌入到标签中)
脚本模式(分离于标签的)
<!-- 内联模式相当于直接调用代码 以浏览器本身来直接执行 window帮忙执行 -->
<!-- 在里面直接嵌入代码 -->
<button onclick="alert('你好')">点击弹窗</button>
<!-- 在里面直接调用函数 以执行代码的形式执行 -->
<button onclick="handlerClick()">点击弹窗</button>
<button class="btn">脚本模式</button>
<button class="btn">脚本模式</button>
<script>
function handlerClick(){
alert('hello')
console.log(this)//指向window
}
//脚本模式相当于把对应的onclick当成一个属性 也就是把元素element当成一个对象
var btn = document.querySelector('.btn')//类型为对象
console.log(typeof btn)
// btn['onclick'] = function(){
// console.log('hello world')
// console.log(this)
// }
btn.onclick = function(){
console.log('hello world')
console.log(this)
}
//具名函数
document.querySelectorAll('.btn')[1].onclick = sayHa
function sayHa(){
alert('ha')
}
</script>
内联模式和脚本模式的区别
内联模式相当于属性赋值 里面的代码是window对象帮你执行,而对应的脚本模式里面的this执行当前调用的元素
脚本模式看不见调用函数 内联模式可以直接看到执行的函数名
事件名的分类
事件的构成
触发的对象.on + 事件名 = 处理函数
鼠标事件(mouse)
click 点击事件
dblclick 双击事件
mousedown 鼠标按下
mouseup 鼠标弹起
mouseenter 鼠标移入
mouseleave 鼠标移出
mouseover 鼠标移入
mouseout 鼠标移出
contextmenu 鼠标右键
<div>
<button>按钮</button>
</div>
<script>
var div = document.querySelector('div')
//点击事件
div.onclick = function () {
console.log('点击事件')
}
//双击会触发两次点击
div.ondblclick = function () {
console.log('双击事件')
}
//按下
div.onmousedown = function () {
console.log('按下')
}
// 弹起
div.onmouseup = function () {
console.log('弹起')
}
// 先按下再弹起 再点击
// 并不会向下执行 冒泡从里到外 捕获 从外到里
div.onmouseenter = function () {
console.log('移入 enter')
}
div.onmouseleave = function () {
console.log('移出 leave')
}
//冒泡 会向下执行
div.onmouseover = function () {
console.log('移入 over')
}
div.onmouseout = function () {
console.log('移出 out')
}
div.oncontextmenu = function () {
console.log('鼠标右键')
}
//鼠标移动(动画之类)
div.onmousemove = function () {
console.log('鼠标移动')
}
//在移动端 没有点击 只有触发 touch
注意事项
执行顺序 mousedown -- mouseup --click
mouseenter mouseleave / mouseover mouseout 的区别 ,前者不会发送冒泡事件(子元素不会被触发)后者会发生事件冒泡(子元素会触发)
键盘事件(key)
按下 keydown
弹起 keyup
按下非功能键 keypress (功能不会执行)
非功能键触发过程 keydown keypress keyup
window.onkeydown = function(){
console.log("键摁下")
}
window.onkeyup = function(){
console.log("键盘弹起")
}
window.onkeypress = function(){
console.log("非功能键摁下")
}
HTML事件
window窗口相关事件
- load 加载事件
- unload 卸载事件
- close 关闭
- beforeunload 卸载之前
- beforeprint 打印之前
- error 错误
- resize 重新设置大小
- reset 重置
- scroll 滚动栏滚动
- hashchange hash值变化
- popstate history的state值变化
<script>
window.onload = function(){
console.log('窗口加载时触发')
}
window.onunload = function(){
console.log('窗口卸载时触发')
}
window.onclose = function(){
console.log('窗口关闭时触发')
}
//页面关闭之前
window.onbeforeunload = function(){
console.log('在卸载之前触发')
}
window.onbeforeprint = function(){
console.log('打印之前触发')
}
window.onerror = function(){
console.log('窗口出错时触发')
}
window.onresize = function(){
console.log('窗口可操作空间大小发生变化的时候触发')
}
window.onreset = function(){
console.log('窗口重置位置的时候触发')
}
window.onscroll = function(){
console.log('窗口滚动栏发生位置变化的时候触发')
}
window.onhashchange = function(){
console.log('hash值发生变化的时候触发')
}
window.onpopstate = function(){
console.log('history中state值发生变化的时候触发')
}
</script>
表单相关事件
input 输入
change value值发生变化
focus 获取焦点
blur 失去焦点
select 内容被选择
submit 提交
reset 重置
<from>
<input type="text">
<select name="" id="">
<option value="1">1</option>
<option value="2">2</option>
</select>
<textarea name="" id="" cols="30" rows="10"></textarea>
<button type="reset">重置</button>
<button type="submit">提交</button>
</from>
<script>
var inp = document.querySelector('input')
var select = document.querySelector('select')
var textarea = document.querySelector('textarea')
//输入事件
inp.oninput = function(){
console.log('表单输入')
}
// 必须先失去焦点
inp.onchange = function(){
console.log('值变化')
}
// value改变事件
select.oninput = function(){
console.log('value发生变化')
}
// 获取焦点事件
inp.onfocus = function(){
console.log('获取焦点')
}
// 失去焦点事件
inp.onblur = function(){
console.log('失去焦点')
}
// 选中内容触发的事件
inp.onselect =function(){
console.log('内容选中触发')
}
// form表单的事件 reset submit
document.forms[0].onsubmit = function(){
console.log('提交')
}
document.forms[0].onreset = function(){
console.log('重置')
}
</script>
event
概述
event是一个事件源对象,它包含了事件触发过程的内容,以及对应元素的内容。它会默认传入给对应的事件的处理函数
处理函数的arguments
<button>点击</button>
<script>
var btn = document.querySelector('button')
btn.onclick = function(e){
console.log(arguments)
console.log(arguments.length)//1 当前的这个处理函数内容只有一个参数 这个参数是一个event对象
//pointerEvent对象 这个对象就是一个事件源对象
console.log(arguments[0])//传入第一个实参
// 这个地方的e就相当于是arguments[0]
console.log(e)
console.log(e == arguments[0])
// 这个接收的event对象存在兼容问题 为了防止兼容问题的产生
//兼容写法
e = e|| window.event
}
//从上述可以看出处理的处理函数会被默认传递一个参数这个参数就是对应的事件源对象
// 我们可以直接用形参接收实参的方法 用形参e接收实参event
对应的处理函数的arguments会被默认传递一个参数 这个参数就是对应的事件源对象
事件源对象一般使用形参接收实参的方法 用形参e接收实参event
event对象里面的相关属性
type 触发事件的类型 *
target 触发的目标元素*
currentTarget 当前加事件的元素* 加给谁就是谁
button 鼠标点击的按钮
screenX screenY 获取鼠标在当前屏幕上的位置
pageX pageY 获取鼠标在页面上的位置(包含滚动栏的位置)
clientX clientY 获取鼠标在可视区的位置(不包含滚动栏的位置)
offsetX offsetY 获取鼠标在目标元素上的位置
altKey shiftKey ctrlKey 是否按下对应的功能键*
cancelBubble 取消冒泡*
returnValue 是否执行对应的默认行为*
bubbles 是否冒泡*
<style>
div{
width: 100px;
height: 50px;
background: #000;
}
btn{
margin: 25px;
}
</style>
<body>
<div>
<button>按钮</button>
</div>
<script>
document.querySelector('div>button').onclick = function(e){
//兼容写法
e=e||window.event
console.log(e)
//对应的属性
console.log(e.type)//获取对应的事件名
console.log(e.target)//获取对应的事件的目标元素 目标元素指当前事件的目标元素
console.log('按钮触发了')
console.log(e.currentTarget)//获取当前加事件的元素
//位置 鼠标点击的坐标
//获取鼠标在屏幕的位置不包含滚动栏
console.log(e.screenX)
console.log(e.screenY)//加上导航栏的位置
//获取鼠标点击位置的页面坐标 包含滚动栏
console.log(e.pageX)
console.log(e.pageY)
//获取鼠标在页面可视区位置 不包含滚动栏
console.log(e.clientX)
console.log(e.clientY)
//ctrlKey shiftKey altKey 是否摁着ctrl键 是否摁着shift键 是否摁着alt键
console.log(e.ctrlKey,e.shiftKey,e.altKey)
//按着 0 1 2
console.log(e.button)
//取消冒泡
console.log(e.cancelBubble)//默认返回值为false
//返回的value值 返回true可以走 false不能走 走不走对应默认的行为
console.log(e.returnValue)//默认值为value
// 是否冒泡
console.log(e.bubbles)
}
//点击对应div里面的按钮时 会触发对应的div的点击事件 那么这个事件被称为事件冒泡
document.querySelector('div').onclick = function(e){
console.log('div触发了')
console.log(e.target)//获取对应的事件的目标元素 目标元素指当前事件的目标元素
console.log(e.currentTarget)//获取当前加事件的元素
}
window.onkeypress = function(e){
console.log(e)
//属于键盘事件源的属性
console.log(e.key)//按下的键 返回键的字符串
console.log(e.keyCode)//按下键的ASCII码 返回大写的ASCII码
console.log(e.charCode)//字符键按下才有 ASCII 如果是给keypress事件那么相对应的keyCode和charCode是一致的
}
</script>
</body>
键盘相关的event属性
key 按下的键 返回键的字符串
keyCode 按下键的ASCII码 返回大写的ASCII码
charCode 字符键按下才有 ASCII 如果是给keypress事件那么相对应的keyCode和charCode是一致的
window.onkeypress = function(e){
console.log(e)
//属于键盘事件源的属性
console.log(e.key)//按下的键 返回键的字符串
console.log(e.keyCode)//按下键的ASCII码 返回大写的ASCII码
console.log(e.charCode)//字符键按下才有 ASCII 如果是给keypress事件那么相对应的keyCode和charCode是一致的
}
事件委托机制(事件代理)
概述
事件委托机制就是将自己的事件委托给对应的父元素去添加,在内部利用对应的target来指向执行元素的特性来进行相关操作
示例
给所有的li添加一个点击事件点击添加背景色
注意事项
如果需要使用事件委托 那么对应的事件一定要支持事件冒泡(利用事件冒泡来完成操作的)
如移入移出功能需要添加事件委托 那么必须使用mouseover/mouseout 不能使用mouseenter/mouseleave
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
<script>
//原本的做法 获取所有的li 遍历添加点击事件
// 利用事件委托 将对应的点击事件委托给对应的父元素 ul
var ul = document.querySelector('ul')
ul.onmouseout = function (e) {
e = e || window.event
//利用e.target来获取对应的执行的元素
if (e.target.tagName == 'LI') {
// 排他思想
// 将所有的li变为无色
for (var li of ul.children) {
li.style.backgroundColor = '#fff'
}
//添加背景色
e.target.style.backgroundColor = '#f00'
}
}
//应用场景 如果有多个共同的元素要添加一个事件 那么可以委托给他的父元素来进行代理
//注意事项 如果需要使用事件委托 那么对应的事件一定要支持事件冒泡(利用事件冒泡来完成操作的)
</script>