event事件
事件由事件源、事件类型、事件处理函数组成。
- 触发谁的事件:事件源
- 触发什么事件:事件类型
- 触发后做什么:事件处理函数
onclick、onload、onscroll、onresize
事件的绑定方式
-
dom0级的事件绑定方式 ==> .onxxxx
- 一旦写了第二个事件,那么第一个就会被覆盖
oDiv.onclick = function () { console.log(this)
-
dom2级事件绑定 ==> :addEventListener
- 这个方法不兼容,ie的低版本里面使用addEvent
oDiv.addEventListener('click', function () { console.log('我是第一个事件') }) // oDiv.addEventListener('click', clickHandler)
-
事件监听
.addEventListener(‘事件类型’,事件处理函数,[冒泡还是捕获])
事件的解绑方式
- dom0级事件的解绑:
元素.onxxxx = null
- 同类事件会被覆盖并且情况
oDiv.onclick = null
-
dom2级事件的解绑:
元素.removeEventListener(‘事件的类型’,要解绑的事件处理函数,[冒泡还是捕获])
- 用于解除指定元素的事件监听器
oDiv.removeEventListener('click', clickHandler)
事件派发
向一个指定的事件目标派发一个事件,可以是原生事件也可以是自定义事件
- 抢票软件,不用手动点击,他可以通过代码触发点击事件
语法:元素.dispatchEvent(事件对象)
事件对象
触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。
包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。例如,鼠标操作导致的事件对象中,包含鼠标为位置的信息,而键盘操作导致的事件对象中,会包含与按下的键有关的信息。所有的浏览器都支持event对象,但支持方式不同。
每次事件触发后,会有一个对象记录:事件类型,你点击的位置,你点击的元素…,每次事件对象都是不同的
- 我们经常打10086客服电话,客服接到我们的电话后,会把客户名称,接待的事件、客户的诉求…记录下来,每一次客服电话都会生成一条客服记录,每次客服记录的内容都是不同的
获取事件对象
在事件处理函数中有一个event对象,记录的是本次事件的一些描述信息。
事件处理函数之所以有两个,是因为有的浏览器只能用window.event
- 兼容写法: e = e||window.event
事件对象常用的方法
- preventDefault():阻止事件的默认操作
- stopPropagation():阻止事件传播
- return false:dom0级阻止事件的默认操作
点击事件光标坐标点的获取
事件对象中有点击时鼠标的坐标,坐标取决于你用哪个坐标系:
-
相对于你点击的元素
语法:事件对象.offsetX 和 事件对象.offsetY
-
相对于浏览器的可视窗口区域
语法:事件对象.clientX 和 事件对象.clientY
-
相对于页面
语法:事件对象.pageX 和 事件对象.pageX
相对事件源的坐标
offsetLeft和offsetTop获取相对于offsetParent父元素的横向坐标和纵向坐标
offsetParent:最近的有定位属性的祖先级,如果都没有定位,那么就是body
点击按键信息
- 我们的鼠标一般有两个以上的按键,左键、右键 等等
- 我们的事件对象里面可以分别出来你点是左键还是右键
- 语法:事件对象.button
- 0代表鼠标左键 1代表滚轮 2代表鼠标右键
switch (flag) {
case 0: console.log('你按下的应该是左键吧'); break
case 1: console.log('你按下的应该是滚轮键吧'); break
case 2: console.log('你按下的应该是右键吧'); break
}
常见的事件
-
浏览器事件 bom
load 页面全部加载完成触发
resize 页面大小改变的时候触发
scroll 页面滚动条滚动的时候触发
-
鼠标事件
click 点击事件
dblclick 双击事件
contextmenu 右键打开快捷菜单
mousedown 鼠标按下
mouseup 鼠标抬起
mousemove 鼠标移动 当鼠标移入元素或子元素 都会触发事件
mouseover 鼠标移入
mouseout 鼠标移出
mouseenter 鼠标移入 当鼠标移入自己才会触发事件,与子元素无关
mouseleave 鼠标移出
-
键盘事件
keydown 按下键盘上任意一个按键的时候触发,如果按着不放,会重复触发
keypress 按下键盘上的字符键触发,如果按着不放,会重复触发
keyup 释放键盘上的按键
-
表单事件
change 表单内容改变到时候触发
input 表单内容输入的时候触发
submit 表单提交事件
blur 失去焦点
focus 获取焦点
键盘按键
不是所有的元素都可以绑定键盘事件,一般只能在页面的各种表单元素和document绑定键盘事件
键盘每一个按键都有一个独立编码–ascii码可以判断按下的是哪个键
语法:事件对象.keyCode || 事件对象.which
-
常见的按键编码:
enter 13
space 32
A 65
a 97inp.addEventListener('keydown', function (e) { var code = e.keyCode switch (code) { case 65: inp.style.backgroundColor = 'red'; break; case 66: inp.style.backgroundColor = 'blue'; break; case 67: inp.style.backgroundColor = 'green'; break; } })
-
组合按键
主要是 alt、shift、ctrl、win
当我按下一个按键的时候,判断这四个按键有没有也被按下了
事件对象.altKey 事件对象.shiftKey
事件对象.ctrlKey 事件对象.metaKey
当按键按下了,返回true否则就是false
事件传播
当大盒子嵌套小盒子,并且两个盒子都有自己的点击事件时,我点击了内部的盒子,两个盒子的事件都被触发,因为我们点击在金色的盒子上面的时候,也是点击在红色的盒子上。
-
传播层级:
inner => middle => outer => body => html => document => window
-
注意:
- 只会传播同类事件
- 只会从点击元素开始按html结构逐层向上,通通触发
- 内部元素不管内有注册事件处理函数,只要上层元素有这个事件,上层的就会触发
事件目标
事件会从自己开始,直到window的所有相同事件都触发。
事件目标就是注册了某个事件的对象,如果要执行事件,就必须指定事件类型和事件目标。在JavaScript中,最常用的事件目标就是Window、Document和Element
事件对象.target (兼容写法:事件对象.srcElement)
事件传播的冒泡机制
从事件的目标的事件处理函数开始,从下依次向上,会向自己的父级元素传播,逐级传播,就会到达body、html,之后传播到Document,最后到Window,直到window的事件处理函数执行
语法:元素.addEventListener(‘事件类型’,‘事件处理函数’,是否冒泡)
- 注意:js使用dom2绑定事件第三个参数默认为false也就是冒泡
事件传播的捕获机制
从window的事件处理函数函数开始,从上依次向下,直到事件目标的事件处理函数执行。
语法:元素.addEventListener(‘事件类型’,‘事件处理函数’,是否捕获)
- 注意:js使用dom2绑定事件第三个参数默认为true也就是捕获
阻止事件传播
阻止事件传播,并不能暂停自己事件处理函数的代码,只是不再进行事件传播机制
语法:事件对象.stopPropagetion()
兼容写法:事件对象.cancelBubble = true (ie678只能用这个)
阻止默认行为
我们不需要写代码注册就能发生的事件就是默认行为,例如:
-
鼠标右键在浏览器点击会自动弹出菜单
-
a标签会自己跳转
-
form表单的submit按钮,也可以触发跳转
语法:事件对象.preventDefault()
return false:dom0级可使用
var oA = document.querySelector('a')
oA.onclick = function (e) {
// 获取跳转的地址 打印看看
console.log(this.href)
e.preventDefault()
}
// 阻止鼠标右键
var oDiv = document.querySelector('div')
// 注册鼠标右键的快捷菜单
oDiv.oncontextmenu = function () {
console.log('打开了右键菜单')
return false
}
事件委托
事件委托也叫事件代理,”事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。 因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件,因此我就可以把子元素的事件委托给父元素来做。
-
好处:
可以大量节省内存占用
可以减少事件绑定的次数
可以实现当新增子对象时无需再次对其绑定(动态绑定事件)
<ul id="ul">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul><button id="btn">点我添加一个li</button>
事件委托具体实现:
var ul = document.getElementById("ul");
ul.onclick = function (event) {
event = event || window.event;
var target = event.target;
// 获取目标元素
if (target.nodeName == 'LI') {
alert(target.innerHTML);
}
}
// 为按钮绑定点击事件
var btn = document.getElementById('btn');
btn.onclick = function () {
var li = document.createElement('li');
// 新增li的内容为ul当前子元素的个数
li.textContent = ul.children.length;
ul.appendChild(li);
}
移动端触摸事件
- touchstart : 手指触摸屏幕时触发
- touchmove : 手指在屏幕上移动时触发
- touchend :手指离开屏幕的时候触发
属性(是数组):
- touches: 当前屏幕上所有触摸点的列表
- targetTouches: 当前对象上所有触摸点的列表
- changedTouches: 涉及当前(引发)事件的触摸点的列表