事件类型与事件对象

DOM中的事件对象

在DOM级事件处理程序中,无论使用的是哪一级的DOM事件处理程序,都会将一个event对象传入到事件处理程序当中。

对于所有事件,一般都会有下列成员

属性/方法类型说明
bubblesBoolean表明事件是否可以冒泡
cancelableBoolean是否可以取消事件的默认行为
currentTargetElement事件处理程序当前正在到达并处理事件的那个元素
defaultPreventedBoolean为true表示已经调用preventDefault()——DOM3级事件新增
detailInteger与事件相关的细节部分
eventPhaseInteger调用事件处理程序的阶段 1:捕获 2:处于目标3:冒泡
preventDefault()Function取消事件的默认行为
stopImmediatePropagation()Function取消事件进一步冒泡,同时阻止事件处理程序被调用
stopPropagation()Function取消事件的进一步冒泡
targetElement事件的目标
typeString事件的类型

在事件处理程序内部,对象this始终等于currentTarget的值。
注意区分target和currentTarget:如果事件处理程序在目标元素上,那么这两个值相等。但是如果事件处理程序在目标元素的父节点上,那么这两个值就是不相等的

let btn = document.getElementById('mybtn')
btn.onclick = function(event){
	event.currentTarget === event.target //true
}
let b = document.body
b.onclick = function(event){
	event.currentTarget === event.target //false
	currentTarget //body
	target //mybtn
}

阻止浏览器默认行为

W3C的方法是e.preventDefault(),IE则是使用e.returnValue = false

preventDefault是事件对象Event的一个方法,作用是取消一个目标元素的默认行为。如果元素没有默认行为,调用无效。什么元素有默认行为呢?如链接点我,提交按钮等

return false:
JS的return false只会阻止默认行为,而jQuery则既阻止默认行为又防止对象冒泡
阻止浏览器默认行为兼容:

function stopDefault(e) {
    var e = e || window.event;
    if (e && e.preventDefault){
        e.preventDefault();
    }else{
        e.returnValue = false;
    }
    return false;
}

注意:只有cancelable属性设置为true时才能过使用preventDefault取消其默认行为

阻止事件冒泡

W3C的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true

stopPropagation是事件对象Event的一个方法,作用是阻止目标元素的冒泡事件,但是不会阻止默认行为

注意,由于IE不支持事件捕获,因此e.cancelBubble = true只能停止事件冒泡,但是e.stopPropagation()可以同时取消事件捕获和事件冒泡

阻止事件冒泡兼容:

function stopPropagation(e) {
    var e = e || window.event;
    if ( e && e.stopPropagation ){
        e.stopPropagation();
    }else{
        e.cancelBubble = true;
    }
}

事件类型

UI事件

UI事件指的是不一定与用户操作有关的事件

  • load:页面完全加载后在window上触发,当所有框架加载完毕后再框架集上触发,当图像加载完毕后在img元素上触发。
  • unload:当页面完全卸载后在window上触发,当所有框架都卸载后在框架集上触发。
  • resize:当窗口或框架大小变化在window或框架上面触发
  • scroll:当用户滚动带滚动条的元素时在该元素上面触发

焦点事件

  • blur:元素失去焦点时触发,不可以冒泡
  • focus:元素获得焦点时触发,不可以冒泡
  • focusin:元素获得焦点触发,可以冒泡
  • focusout:元素失去焦点时触发,可以冒泡

注意:虽然blur和focus不冒泡,但是可以在事件捕获阶段侦听到他们。

当焦点从一个元素移动到另一个元素时,会依次触发下面这些事件

  1. focusout
  2. focusin
  3. blur
  4. focus

鼠标事件

鼠标事件描述
click按下鼠标时触发
dblclick双击鼠标时触发
mousedown按下鼠标键时触发
mouseup释放按下鼠标键触发
mousemove鼠标在节点内部移动触发,持续移动,事件会持续触发(会有性能问题)
mouseenter鼠标首次进入节点触发,进入子节点不会触发。(在节点内只会触发一次)
mouseover鼠标进入节点触发,进入子节点会再一次触发
mouseout鼠标离开节点触发,离开父节点也会触发
mouseleave鼠标离开节点触发,离开父节点不会触发
contextmenu鼠标右键(右键菜单)前触发,或按下右键菜单时触发
wheel滚动鼠标的滚轮时触发,继承WheelEvent接口

mouseover 和 mouseenter 的共同点:鼠标进入一个节点触发

区别:

  • mouseover 会在子节点触发多次
  • mouseenter 只触发一次

mouseout 和 mouseleave 共同点: 鼠标离开一个节点时触发

区别:

在父元素内部离开一个子元素时,mouseout事件会触发。
在父元素内部离开一个子元素时,mouseout事件不会触发。

鼠标事件的位置

  • 客户区坐标位置
    鼠标事件是在浏览器的窗口特定位置上发生的,这个位置信息保存在事件对象的clientX和clientY
  • 页面坐标位置
    这个位置信心告诉你鼠标事件是在页面中什么位置发生的,保存在pageX和pageY中

PageX和clientX ,这个两个比较容易搞混,

  • PageX:鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化,换句话说,从滚动页面的左上角开始计算
  • clientX:鼠标在页面上可视区域的位置,从浏览器可视区域左上角开始,即是以浏览器滑动条此刻的滑动到的位置为参考点,随滑动条移动 而变化.

移动端设备

由于没有鼠标,所以移动端的鼠标事件有一定区别与变化

  • 不支持dbclick事件,双击浏览器窗口会放大画面,而且没有办法改变这个事件
  • 点击可单机元素会触发mouseover事件,如果这个事件不会导致屏幕发生变化,那么会依次发生mousedown、mouseup、click事件。否则不再有其他事件发生
  • mousemove事件也会触发mouseover和mouseout事件

触摸事件

  • touchstart:手指触摸屏幕时触发
  • touchmove:手指在屏幕上滑动时连续触发。在这个事件发生期间调用preventDefault()可以阻止滚动
  • touchend:手指从屏幕移开时触发
  • touchcancel:系统停止跟踪触摸事件时触发

html5事件

contextmenu事件

调出上下文菜单触发的事件,简单来说就是在windows下点击鼠标右键,在mac下Ctrl+单击。有时候我们需要给网页设置自定义的上下文菜单,于是contextmenu事件出现了。

由于这个事件是冒泡的,所以可以为document指定一个事件处理程序,用来代理页面中发生的所有此类事件。搭配preventDefault使用可以取消默认的上下文菜单,从而自定义上下文菜单。然后通过clientX和clientY来设置自定义菜单显示的位置,设置visible来控制自定义菜单的显示与隐藏。

beforeunload事件

在页面卸载前触发事件,让开发者在页面被卸载前阻止操作,但是需要注意的是,这个事件旨在页面卸载前提醒用户,询问用户是否离开页面,不能完全阻止页面被卸载

DOMcontentloaded事件

  • 当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。
  • load 仅用于检测一个完全加载的页面,页面的html、css、js、图片等资源都已经加载完之后才会触发 load 事件。

hashchange事件

HTML5新增的hashchange事件,以便在URL参数列表发生变化时通知开发者

前端路由的hash实现

www.test.com/#/ 就是 Hash URL,当 # 后面的哈希值发生变化时,可以通过 hashchange 事件来监听到 URL的变化,从而进行跳转页面,并且无论哈希值如何变化,服务端接收到的 URL 请求永远是 www.test.com

window.addEventListener('hashchange', () => {
  // ... 具体逻辑
})

Hash 模式相对来说更简单,并且兼容性也更好

前端路由的history实现
History 模式是 HTML5 新推出的功能,主要使用 history.pushState 和 history.replaceState 改变 URL

通过 History 模式改变 URL 同样不会引起页面的刷新,只会更新浏览器的历史记录。

// 新增历史记录
history.pushState(stateObject, title, URL)
// 替换当前历史记录
history.replaceState(stateObject, title, URL)

当用户做出浏览器动作时,比如点击后退按钮时会触发 popState 事件

window.addEventListener('popstate', e => {
  // e.state 就是 pushState(stateObject) 中的 stateObject
  console.log(e.state)
})

两种模式对比

  • Hash模式只可以更改 # 后面的内容,History 模式可以通过 API 设置任意的同源 URL
  • History 模式可以通过 API 添加任意类型的数据到历史记录中,Hash 模式只能更改哈希值,也就是字符串
  • Hash 模式无需后端配置,并且兼容性好。History 模式在用户手动输入地址或者刷新页面的时候会发起 URL 请求,后端需要配置 index.html 页面用于匹配不到静态资源(就像nginx配置react路由)

关于冒泡

不支持冒泡的事件

UI事件

  • load
  • unload
  • scroll
  • resize

焦点事件

  • blur
  • focus

鼠标事件

  • mouseleave
  • mouseenter
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值