JS中常见事件和事件流理解
事件
浏览器事件
onload事件
当html都加载完成,才执行。一般是控制资源的获取,必须是加载完成才能获取,就要使用onload
// 当文档加载完成后执行一些操作
window.onload = function(){
console.log("页面加载完成")
}
窗口事件
- onresize事件(可视尺寸改变)
在窗口尺寸发生改变时触发
window.onresize = function(){
console.log('窗口尺寸改变了')
}
- onscroll事件(滚动条位置改变)
滚动条位置改变时触发。
window.onscroll = function(){
console.log('滚动条发生了滚动')
}
浏览器卷去的尺寸(当滚动条滚动时,页面被遮盖掉的尺寸)
//卷去的高度
//当有<!DOCTYPE html>标签时
document.documentElement.scrollTop
//没有<!DOCTYPE html>标签时
document.body.scrollTop
//常用写法
window.onscroll = function(){
var height = document.documentElement.scrollTop ||document.body.scrollTop
console.log(height)
}
//卷去的宽度
window.onscroll = function(){
var width = document.documentElement.scrollLeft || document.body.scrollLeft
console.log(width)
}
🌟鼠标事件
click
:点击事件dblclick
:双击事件contextmenu
: 右键单击事件mousedown
:鼠标左键按下事件mouseup
:鼠标左键抬起事件mousemove
:鼠标移动mouseover
:鼠标移入事件,移入后代也会触发mouseout
:鼠标移出事件mouseenter
:鼠标移入事件,移入后代不会触发mouseleave
:鼠标移出事件
键盘事件
keyup
: 键盘抬起事件keydown
: 键盘按下事件keypress
: 键盘按下再抬起事件,你按下的按键必须和键入内容一致
🌟表单事件
change
: 表单内容改变,且失去焦点时触发input
: 表单内容输入事件submit
: 表单提交事件blur
: 失去焦点事件focus
获取焦点事件reset
表单的重置
🌟事件对象event
任何事件的触发都会产生event对象
event对象属性
属性 | 说明 |
---|---|
event.type | type属性指示事件类型。 |
event.which | which 属性指示按了哪个键或按钮。 |
event.clientX | 事件触发时鼠标距离窗口左边的距离(可视区域)。 |
event.clientY | 事件触发时鼠标距离窗口上边的距离(可视区域)。 |
event.screenX | 事件触发时鼠标距离屏幕左边的距离。 |
event.screenY | 事件触发时鼠标距离屏幕上边的距离。 |
event.button | 返回值为0,左键;返回值为1,中键;返回值为2,右键 |
event.offsetX | 当鼠标事件发生时,鼠标相对于事件发生元素左边的位置 |
event.offsetY | 当鼠标事件发生时,鼠标相对于事件发生元素顶部的位置 |
event.pageX | 当鼠标事件发生时.相对于文档窗口左边的位置 |
event.pageY | 当鼠标事件发生时.相对于文档窗口顶部的位置 |
事件绑定的三种方式
- 直接在 HTML 中绑定事件
<button onclick="alert('Hello world!')">Click me</button>
这种方式比较简单,但不太灵活,因为只能在 HTML 中绑定事件,并且只能绑定一个事件处理函数。
- 使用 DOM 元素的属性绑定事件
DOM0级事件处理程序(on…)
var button = document.querySelector('button');
button.onclick = function() {
alert('Hello world!');
};
这种方式比 HTML 中绑定事件更灵活,因为可以在 JavaScript 代码中动态绑定事件处理函数。但是,同样只能绑定一个事件处理函数。(同类型事件,后面覆盖前面)
- 使用 addEventListener() 方法绑定事件(常用)
DOM2级事件处理程序
这种方式是最常用的一种方式,因为它可以同时绑定多个事件处理函数,而且可以在事件冒泡或捕获阶段中绑定事件处理函数。
const button = document.querySelector('button');
button.addEventListener('click', function() {
alert('Hello world!');
});
此外,addEventListener() 还可以接受第三个参数,用于指定事件是否在捕获阶段执行,默认为在冒泡阶段执行。
const button = document.querySelector('button');
button.addEventListener('click', function() {
alert('Hello world!');
}, true); // 捕获阶段执行
事件移除
- DOM移除节点
removeChild、replaceChild()
通过DOM操作直接将节点移除,则绑定在节点上事件也不存在了。
- DOM2级,移除事件监听器(常用)
节点对象.removeEventListener(事件类型,事件处理,[事件流])
事件流
在JavaScript中,事件流就是事件在目标元素和祖先元素间的触发顺序。按照事件传播的顺序,事件流可分两种:
1、冒泡型事件流,事件的传播是从最特定的事件目标到最不特定的事件目标;
2、捕获型事件流,事件的传播是从最不特定的事件目标到最特定的事件目标。
一个完整的JS事件流是从window开始,最后回到window的一个过程。事件流被分为三个阶段:捕获过程、目标过程和冒泡过程。(类似雷达搜索过程)
- 捕获阶段
事件从文档的根节点出发,随着 DOM 树的结构向事件的目标节点流去。途中经过各个层次的 DOM 节点,并在各节点上触发捕获事件,直到到达事件的目标节点。
捕获阶段的主要任务是建立传播路径,在冒泡阶段,事件会通过这个路径回溯到文档跟节点。
- 目标阶段
当事件到达目标节点的,事件就进入了目标阶段。事件在目标节点上被触发(执行事件对应的函数),然后会逆向回流,直到传播至最外层的文档节点。
- 冒泡阶段
事件在目标元素上触发后,并不在这个元素上终止。它会随着 DOM 树一层层向上冒泡,直到到达最外层的根节点。
事件冒泡和事件委托(代理事件监听)
事件冒泡是指当一个元素上的事件被触发后,该事件将沿着其父元素向上传递,直到传递到文档根元素。事件冒泡机制可以用来处理元素嵌套的情况,避免在每个子元素上都绑定事件。
事件委托是指将事件处理程序绑定到一个父元素上,而不是绑定到子元素上。当一个子元素上的事件被触发时,该事件将通过事件冒泡机制传递到父元素,然后被父元素的事件处理程序处理。使用事件委托可以提高性能,因为只需要在一个父元素上绑定事件处理程序,而不是在多个子元素上绑定事件处理程序。
事件委托的优点
- 可以大量节省内存占用,减少事件注册
- 可以实现当新增子对象时无需再次对其绑定(动态绑定事件)
使用事件委托注意事项
使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。
事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。
如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。
eg:
<ul>
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
</ul>
<script>
ul.addEventListener('mouseover', ul_over)
function ul_over(eve) {
target = eve.target;
target.classList.add('active')
//获取li内容并放入input框
input.value = target.innerHTML;
}
/*
在ul上绑定鼠标滑入事件,
当鼠标滑过li时,会触发事件冒泡机制,从当前li开始向上级传递,并检索所经过节点是否有同类型事件处理程序。直到传递到ul,遇到鼠标滑过事件处理程序,才开始执行事件处理程序。
并且可通过event对象中target属性返回值得到本次是滑过哪个li触发的冒泡。
*/
</script>
阻止事件冒泡
event.stopPropagation();
说明:stopPropagation是事件对象Event的一个方法,作用是阻止目标元素事件冒泡到父级元素。
阻止浏览器默认行为
e.preventDefault();
通用方法:
e.preventDefault();
说明:preventDefault是事件对象Event的一个方法,作用是取消一个目标元素的默认行为。如果元素没有默认行为,调用无效。
IE则是使用:
e.returnValue = false;
也可以用 return false;不仅返回值也会停止代码向下执行
函数封装
function stopDefault(event) {
var e = event || window.event;
if (e.preventDefault){
e.preventDefault(); // 标准浏览器
}else{
e.returnValue = false; // IE浏览器
}
}