在文档、浏览器、标签元素等元素在特定状态下触发的行为即为事件,比如用户的单击行为、表单内容的改变行为即为事件,我们可以为不同的事件定义处理程序。JS使用异步事件驱动的形式管理事件。

一、处理程序

事件的目的是要触发事件后执行一段代码,我们称这类代码为事件处理程序。

1.HTML绑定
可以在html元素上设置事件处理程序,浏览器解析后会绑定到DOM属性中
注意:绑定函数或方法时需要加上括号   <button onclick="show()">
2.DOM绑定
也可以将事件处理程序绑定到DOM属性中,但使用setAttribute方法设置事件处理程序无效,且无法为事件类型绑定多个事件处理程序,
<script>
  const app = document.querySelector('#app')
  app.onclick = function () {
    this.style.color = 'red'
  }
</script>
3.事件侦听
可以对同一事件类型设置多个事件处理程序,按设置的顺序先后执行

const app = document.querySelector('#app')
  app.addEventListener('click', function () {
    this.style.color = 'red'
  })
可传入三个参数:
参数1——事件类型
参数2——事件处理程序 如果参数2是对象 那么该对象的handleEvent 方***做为事件处理程序执行
参数3——定制选项:once:true 只执行一次事件   capture:true/false 捕获阶段传播到该 EventTarget 时触发  passive:true listener 永远不会调用 preventDefault()

二、事件对象

执行事件处理程序时,会产生当前事件相关信息的对象,即为事件对事。大部分浏览器将事件对象保存到window.event中,有些浏览器会将事件对象做为事件处理程序的参数传递
事件对象的常用参数有:
属性 说明
type 事件类型
target 事件目标对象,冒泡的父级通过该属性可以找到在哪个元素上执行了事件
currentTarget 当前执行事件的对象
timeStamp 事件发生时间
x 相对窗口的X坐标
y 相对窗口的Y坐标
clientX 相对窗口的X坐标
clientY 相对窗口的Y坐标
screenX 相对计算机屏幕的X坐标
screenY 相对计算机屏幕的Y坐标
pageX 相对于文档的X坐标
pageY 相对于文档的Y坐标
offsetX 相对于事件对象的X坐标
offsetY 相对于事件对象的Y坐标
layerX 相对于父级定位的X坐标
layerY 相对于父级定位的Y坐标
path 冒泡的路径
altKey 是否按了alt键
shiftKey 是否按了shift键
metaKey 是否按了媒体键
window.pageXOffset 文档参考窗口水平滚动的距离
window.pageYOffset 文档参考窗口垂直滚动的距离
(注:在之前的去哪儿网城市列表的滑动效果  计算距离就用到了当前点击事件的坐标属性)

三、冒泡捕获和默认行为

1.冒泡行为:
冒泡就是向上执行父级元素的事件处理程序,一直到HTML标签位置
注:focus事件不会冒泡  event.target 可以在事件中(包括父级元素中)得到事件目标元素(即最底层的产生事件的对象)  event.currentTarget == this 即当前执行事件的对象
如:
父级为ul  底层为li
<ul>
  <li>1111</li>
  <li>2222</li>
</ul>
则 当点击li的时候 可以在父级元素ul这一层通过event.target 可以得到当前的时间目标元素(即li)
<script>
  const ul = document.querySelector('ul')
  ul.addEventListener('click', () => {
    if (event.target.tagName === 'LI') event.target.classList.toggle('hd')
  })
</script>

2.阻止冒泡
 event.stopPropagation() ——阻止冒泡传递  
如果同一类型事件绑定多个事件处理程序 event.stopPropagation() 只阻止当前的事件处理程序 冒泡
但  event.stopImmediatePropagation() 可以阻止事件冒泡并且阻止相同事件的其他事件处理程序被调用
3.事件捕获
向下传递到目标对象的过程即为事件捕获  事件执行顺序为————捕获 > 事件目标 > 冒泡阶段  
***代理
借助冒泡思路,可以不为子元素设置事件,而将事件设置在父级。通过父级事件对象的event.target查找子元素,并对子元素做出处理。
还可以通过事件代理对未来元素进行事件绑定:
<div id="app">
  <h2>AAAAA</h2>
</div>

<script>
  function show() {
    console.log(this.textContent)
  }
  const app = document.querySelector('#app')
  const h2 = document.querySelectorAll('h2')
  app.addEventListener('click', () => {
    show.call(event.target)
  })
  let newH2 = document.createElement('h2')
  newH2.textContent = 'BBBBB'
  app.append(newH2)
</script>
5.默认行为:
些对象会设置默认事件处理程序,一般在用户定义的处理程序后执行。
使用event.preventDefault() ——————阻止默认行为

四、典型事件

1.窗口文档
事件名 说明
window.onload 文档解析及外部资源加载后
DOMContentLoaded 文档解析后不需要外部资源加载,只能使用addEventListener设置
window.beforeunload 文档刷新或关闭时
window.unload 文档卸载时
scroll 页面滚动时
2.鼠标事件
事件名 说明
click 鼠标单击事件,同时触发 mousedown/mouseup
dblclick 鼠标双击事件
contextmenu 点击右键后显示的所在环境的菜单
mousedown 鼠标按下
mouseup 鼠标抬起时
mousemove 鼠标移动时
mouseover 鼠标移动时
mouseout 鼠标从元素上离开时
mouseup 鼠标抬起时
mouseenter 鼠标移入时触发,不产生冒泡行为
mosueleave 鼠标移出时触发,不产生冒泡行为
oncopy 复制内容时触发
scroll 元素滚动时,可以为元素设置overflow:auto; 产生滚动条来测试

鼠标事件产生的事件对象包含相对应的属性

属性 说明
which 执行mousedown/mouseup时,显示所按的键 1左键,2中键,3右键
clientX 相对窗口X坐标
clientY 相对窗口Y坐标
pageX 相对于文档的X坐标
pageY 相对于文档的Y坐标
offsetX 目标元素内部的X坐标
offsetY 目标元素内部的Y坐标
altKey 是否按了alt键
ctrlKey 是否按了ctlr键
shiftKey 是否按了shift键
metaKey 是否按了媒体键
relatedTarget mouseover事件时从哪个元素来的,mouseout事件时指要移动到的元素。当无来源(在自身上移动)或移动到窗口外时值为null
3.键盘事件
事件名 说明
Keydown 键盘按下时,一直按键不松开时keydown事件会重复触发
keyup 按键抬起时

鼠标事件产生的事件对象包含相对应的属性

属性 说明
keyCode 返回键盘的ASCII字符数字
code 按键码,字符以Key开始,数字以Digit开始,特殊字符有专属名子。左右ALT键字符不同。
不同布局的键盘值会不同
key 按键的字符含义表示,大小写不同。不能区分左右ALT等。不同语言操作系统下值会不同
altKey 是否按了alt键
ctrlKey 是否按了ctlr键
shiftKey 是否按了shift键
metaKey 是否按了媒体键
4.表单事件
事件类型 说明
focus 获取焦点事件
blur 失去焦点事件
element.focus() 让元素强制获取焦点
element.blur() 让元素失去焦点
change 文本框在内容发生改变并失去焦点时触发,select/checkbox/radio选项改变时触发事件
input 内容改变时触发,包括粘贴内容或语音输入内容都会触发事件
submit 提交表单