为了账号安全,请及时绑定邮箱和手机立即绑定

一起扫荡javascript(二)—— about event关于事件

标签:
JavaScript

            今天呢,我们来说说javascript的事件,事件是什么?啊,我知道,点击事件click,嗯,很好,你答对了javascript里面N多种触发机制(事件)里的鼠标事件相关N多种事件中的点击事件。

            呐下面的代码是不是很常见的一个事件?

document.querySelector('button').ondblclick = () => console.log("1");

             把上面的小例子稍微修改下,看看输出什么?

document.querySelector('button').ondblclick = (e) => console.log(e);

           但是啊,事件实际上有很多,事件在我的理解它更像是某种触发,某种对行为的监测,同时在某种行为被触发后程序作出的应激性反应(条件反射)。比如点击双击鼠标,移动鼠标,鼠标移入移出某个区域...有了鼠标了,我们平时能跟电脑互动的其实还有键盘,键盘按下,抬起...此外呢,当我们的文件在上传或者下载(思考下这算不算一种行为呢?),还有呢,一个输入框对它各种操作的时候,又有哪些事件?还有吗?我们复制的时候呢?是怎样的?要选定吧?要剪贴到剪贴板吧?我们的窗口被我们各种调整呢?算不算一个事件?当然事件还有很多很多...一时半会列不完,我们这里把大部分的整理下。

            首先是鼠标相关的:

    // 鼠标事件相关
// /ondblclick : 鼠标单击双击事件
// onmouseover/onmouseout : 鼠标滑过事件
// onmousemove : 鼠标移动事件
// onmouseenter/onmouseleave : 鼠标移入移出事件
// onmousedown/onmouseup : 鼠标按下与松开事件
// oncontextmenu : 鼠标右键菜单点击后触发的事件

document.onmousemove = (e) => console.log("x = " + e.clientX + ", y = " 
+ e.clientY);

            接下来呢是键盘的:

    // 键盘相关
// onkeyup : 键盘抬起
// onkeydown : 键盘按下
// onkeypress : 键盘被按下或被抬起

document.querySelector('input').onkeypress = (e) => console.log(e.target);

            接下来呢跟输入有关的:

    // 输入相关
// onchange : 当输入框的内容有所变化时,跟onmousemove一样容易失去焦点
// input : 算是onchange的进化版本,不会失去焦点

document.querySelector('input').oninput = (e) => console.log(e.target);

            还有其他(合起来了写一块):

//onsubmit      确认按钮点击
//onundo        在文档执行 undo 时运行的脚本
//onunload      页面已下载或者浏览器窗口关闭
//onstorage     浏览器有本地存储跟临时存储localstorage和sessionstorage区域更新时执行
//onpagehide    窗口隐藏
//onafterprint/onbeforeprint 文档打印之前跟之后after个before
//onmessage     消息被触发//...还有好多好多,form表单改变时的各种事件...最好全部过一遍

            事件冒泡与捕获:

            啥意思?就是为什么还要什么捕获和冒泡,简简单单不含任何杂质多好?我们先理解一个前提,这个前提很重要——标签实际上是一个套着一个的。我们平时写一个标签,即使是感觉很底层的标签比如这样:

            https://img1.sycdn.imooc.com//5b892ce40001fffe08280323.jpg

            它上面还有body-html-document。

            这个前提告诉我们什么呢?我无论触碰哪个标签,它的父层一定会被触碰到,对吧?那如果说,你和父层绑定的是同一种事件,那我得先触碰谁?谁是老大?浏览器怎么知道得谁先来,剪刀石头布?那肯定不行。

            先看下面这个小例子:

https://img1.sycdn.imooc.com//5b892c850001e68c06590177.jpg

你觉得会弹出什么?

            那就得有一种东西让我们跟浏览器交流,告诉他谁是老大,得谁先来,对吧?告诉浏览器父层是老大,事件触发得它先来,得先完成它的诉求,再轮到小的。这是一种可能对吧?还有呢?反过来,告诉浏览器你是老大,得你先来,父层往后排。这种从你这个小个子往你的长辈冒,就叫冒泡。而从你的长辈再慢慢的往小的(因为儿子可能多个)来抓就叫捕获。是不是很简单?

            那上面这个你有想过为什么是先button再li-ul-div-section?也就是我们刚刚说的小个子的优先,也就是冒泡,为啥?你说浏览器默认冒泡啊,为啥?为什么得冒泡?捕获就不可以吗?因为直接从小的往大的找是不是比较简单?你父亲只有一个,而你儿子可能很多个对吧?浏览器这样默认肯定有它的道理,它要考虑性能啊,没道理石头剪子布谁赢就默认谁啊,对吧?

            事件的冒泡与捕获一般是开始于document也终止于document,也就是:

            即document-html-body-...

            ...-父层-爷爷层-曾爷爷层-...-body-html-document。

            有个比较有意思的是iframe里面也是有个document,所以呢,你会发现你的冒泡啥的被隔绝了。

            下面看看捕获有什么不同:(注意看事件的末端有个true,就是告诉浏览器这些事件用捕获,老大优先,小的轮后)

https://img1.sycdn.imooc.com//5b8936f40001009109510441.jpg

            是不是就从html往小的button一级级过渡啦?

            好了,不扯太远我们再一起看看事件委托吧?

            我们平时有遇到一个东西么?比如某个多级的菜单,某个ul里面有n多个li,你要把这些li都给绑定对应事件,是不是用个for循环啊啥的来绑定?

            大概差不多下面这样,对吧?

https://img1.sycdn.imooc.com//5b8939140001379c09920305.jpg

            但是呢?你这样是不是太多事件了?如果你这里的li很多,甚至li里面嵌套着ul再li,对浏览器的性能负荷会非常大。既然有刚需,那有没有一种办法来解决这样的问题呢?答案是肯定的。

            这种解决方案就是事件委托,先别想着多复杂的样子,我们先来一起看看吧,就把上面的小例子做点小改造,好吧?

            https://img1.sycdn.imooc.com//5b893a9a000187c809070382.jpg

            你觉得这两个一样吗?一样吧?而这个就是比较典型的事件委托的小例子。

            什么意思呢?事件委托就是一个包工头,老板要你做事,他不直接找你,因为老板下面还有很多很多的你,他找谁呢?找包工头,或者说你的主管,把事情委托给他,他全权负责,还记得说冒泡和捕获的时候说的那个前提吗?标签实际上是相互嵌套的,我无论触碰哪个标签,它的父层一定会被触碰到。所以只要把事情委托给你们的主管,跟主管说,嗯要干活了,让这位主管管辖区的某些特定群体来干活。接下来就由主管来分发(里面多出来的参数的li,用js来实现也是可以的,可以自己去试试),下发,这样的流程,你觉得事情会不会更快?

            事件委托另一个好处就是,当页面是动态改变时,不会使绑定的事件失效。啥意思?说得太官方了对吧?好吧,平时有用过分页吗?分页点击下一页,页面重新渲染,但是呢,这时候你的js仅仅是页面初始化的时候加载进来了,刚好绑定的仅仅是第一页下的节点,第二页刷出来的时候事件就没绑定了。比如一个大的div里面有20个小div,每个div都有一个事件,这时候,你去点分页,分页的页面注意这是重点加载是在js脚本运行之后,分页区域里面的dom节点就没有效果了,当然你可以通过一些其他的手段比如监听分页页面加载完毕后重新运行js脚本,但是呢,这样很麻烦还带来很多其他的问题。但是如果我们绑定的是不会改变的那些节点呢?比如大的div下面20个小div,我绑定的是大的div,小div刷了跟大div有没有关系?没有吧?那这时候事件委托是不是产生奇效了,通过向大的div委托事件,再让它自己去分发,即使他手里的工人换了一批,他也知道,而你不知道。事件委托在很多时候都有很大的作用,建议深入去了解它学习它。

            嗯好了,事件的三个补充:冒泡捕获和委托就到这吧。以后想到什么再来加了。








点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
1.3万
获赞与收藏
1519

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消