今天给大家分享一下,修真院官网JS-2任务中可能会使用到的知识点:
1.背景介绍
讲到js的事件机制,我们就能来了解一下什么是事件,先举个例子:
比如说,人都会睡觉,但只有人感到困倦的时候才会去睡觉。让我们来用程序写一下
function sleep() {
do sleep;
}
people.ontired = function(){
sleep();
}
当然我们修真院的师兄弟们都是修仙之人,当然不与这等凡人苟同。
function coding() {
coding;
}
people.ontried=function(){
coding();
}
所以事件这种东西是广泛存于我们周围的,也就是一个触发点,就像一个开关一样,按下灯开关灯就亮了,再按一下就关了,这就是一个事件
把事件放在web中,准确的说是放到浏览器中,事件就会变为用户对浏览器所做的行为的响应。比如简单的点击、键盘、移动鼠标、关闭网页等等,只要浏览器能对用户行为做出响应的,都是web的事件,比如让德国boy怒砸电脑,抱歉浏览器真的无法监听这个“事件”所以算不上web事件
所以,事件是浏览器对用户行为的一个响应。
2.知识剖析
2.1 js的事件驱动
js是事件驱动,正是有这些事件的存在,前端才能和用户联系起来,我们一般不清楚用户对网页做了什么,但是外门知道用户做了那些行为后应该给与怎么样的处理。可以把自己想象成一个地雷兵,在页面中布满地雷了大大小小的“事件地雷”,只要用户不睬上去,我们的代码只能老老实实躺在js中不会触发,只要用户踩到了“地雷”,那么我们的地雷就可以瞬间boom
document.body.οnclick=function(){
alert('boom');
}
如果用户只是打开了网页,没有进行点击,那么这个boom就永远不会弹出,因为js是事件驱动的。
讲了这么多事件驱动,那么总结一下什么是事件驱动好了,事件没有发生,那么我们写的js代码就不会执行,事件是触发代码执行的直接原因。
一般来讲,如果在一个点击事件里写上几个逻辑错误,页面加载的时候是不会给你报错的,浏览器只是看了一眼onclick里面的内容,但不会去执行,自然是不会看到里面的逻辑错误,除非你在里面谢了几个语法错误,加载的时候发现,卧槽,读不通啊,他才会提示错误。当你点击事件触发的时候,js执行了代码,发现里面的逻辑狗屁不通,就会自然而然的报错了
通常我们都会写个window.onload,页面加载完成触发的事件,把要执行的代码放在里面,这样资源加载好了js好操作。但是页面中还存在一个硬性的事件,就是read,js引擎阅读代码事件。如果读到了function 函数名(){...}活着var 函数名=function(){...}这样的结构,它会匆匆扫一眼,不执行里面的代码,然后继续读下去,其他的语句一旦遇到了,js就会去执行它。比如var 变量名或着函数名()这样。这个是read事件,其他事件也类似,只有当前浏览器对用户行为的响应时,js才会执行里面的代码。
2.2 js常见事件
1、窗口事件,只在body和frameset元素中才有效
onload 页面或图片加载完成时
onunload 用户离开页面时
2、表单元素事件,在表单元素中才有效
onchange 框内容改变时
onsubmit 点击提交按钮时
onreset 重新点击鼠标按键时
onselect 文本被选择时
onblur 元素失去焦点时
onfocus 当元素获取焦点时
3、键盘事件,在base,bdo,br,frame,frameset,head,html,iframe,meta,param,script,style,title元素里都无效
onkeydown 按下键盘按键时
onkeypress 按下或按住键盘按键时
onkeyup 放开键盘按键时
4、鼠标事件,在base,bdo,br,frame,frameset,head,html,iframe,meta,param,script,style,title元素里都无效
onclick 鼠标点击一个对象时
ondblclick 鼠标双击一个对象时
onmousedown 鼠标被按下时
onmousemove 鼠标被移动时
onmouseout 鼠标离开元素时
onmouseover 鼠标经过元素时
onmouseup 释放鼠标按键时
5、其他
onresize 当窗口或框架被重新定义尺寸时
onabort 图片下载被打断时
onerror 当加载文档或图片时发生错误时
2.3 js中事件处理程序的几种方式
产生了事件,我们就要去处理它,js中事件处理程序主要有3种方式:
1、HTML事件处理程序
即我们直接在HTML代码中添加事件处理程序,如下面这段代码:
<input id="btn" value="按钮" type="button" οnclick="showmsg();">
<script>
function showmsg(){
alert("HTML添加事件处理");
}
</script>
2、DOM0级事件处理程序
即为指定对象添加事件处理,看下面的一段代码:
input id="btn" value="按钮" type="button">
<script>
var btn= document.getElementById("btn");
btn.οnclick=function(){
alert("DOM级添加事件处理");
}
btn.οnclick=null;//如果想要删除btn的点击事件,将其置为null即可
</script>
3、DOM2级事件处理程序
DOM2也是对特定的对象添加事件处理程序,但是主要涉及到两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和 removeEventListener()。它们都接收三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(是否在捕获阶段处理事件)如果为true,表示在捕获阶段调用事件处理程序,如果是false,表示在冒泡阶段调用事件处理程序,看下面的一段代码:
<input id="btn" value="按钮" type="button">
<script>
var btn=document.getElementById("btn");
btn.addEventListener("click",showmsg,false);//这里我们把最后一个值置为false,即不在捕获阶段处理,一般来说冒泡处
理在各浏览器中兼容性较好
function showmsg(){
alert("DOM级添加事件处理程序");
}
btn.removeEventListener("click",showmsg,false);//如果想要把这个事件删除,只需要传入同样的参数即可
</script>
2.4 事件的三个阶段事件的三个阶段
①捕获阶段:
事件从根节点流向目标节点,途中流经各个DOM节点,在各个节点上触发捕获事件,直到达到目标节点。
捕获阶段的主要任务是建立传播路经,在冒泡阶段根据这个路经回溯到文档根节点
②目标阶段
事件到达目标节点时,就到了目标阶段,事件在目标节点上被触发
③冒泡阶段
事件在目标节点上触发后,不会终止,一层层向上冒,回溯到根节点。
1.事件冒泡(常用)
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5COzMGN0UGZ3EWZlNWLyQTO40CM5EGNtU2Y2ETLiJWZ0MzMkVzLclHbpFGZvwFbsl2az9CXt92Yu4Wd5N3aucmbppWalJWLuNWLzM3auQXZrNWdi5yZtlmLz5mavw1LcpDc0RHaiojIsJye.png)
IE中采用的事件流是事件冒泡,先从具体的接收元素,然后逐步向上传播到不具体的元素。
<body style="height:500px">
<div id="all">
<div>div1</div>
<div>div2</div>
</div>
<script>
document.getElementsByTagName('body')[0].addEventListener('click', function(e) {
alert(1);
}, false);
document.getElementById('all').addEventListener('click', function(e) {
alert(2);
}, false);
</script>
2.事件捕获(少用)
Netscapte采用事件捕获,先由不具体的元素接收事件,最具体的节点最后才接收到事件。
<body style="height:500px">
<div id="all">
<div>div1</div>
<div>div2</div>
</div>
<script>
//将这里的false,改成true.表明body的绑定事件发生在捕获阶段
document.getElementsByTagName('body')[0].addEventListener('click', function(e) {
alert(1);
}, true);
document.getElementById('all').addEventListener('click', function(e) {
alert(2);
}, false);
</script>
3.DOM事件流
3.常见问题
4.解决方案
5.编码实战
6.拓展思考
关于阻止冒泡事件和默认事件
6.1 阻止冒泡事件
其实在非IE浏览器中提供了一个事件对象 stopPropagation,那么在IE浏览器中有通过cancelBubble事件对象可以阻止。
语法部分:
stopPropagation() 方法
定义和用法
不再派发事件。
终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播。调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点。
语法
event.stopPropagation()
说明
该方法将停止事件的传播,阻止它被分派到其他 Document 节点。在事件传播的任何阶段都可以调用它。注意,虽然该方法不能阻止同一个 Document 节点上的其他事件句柄被调用,但是它可以阻止把事件分派到其他节点。
实现效果:
6.2、首先理解一下默认事件:
浏览器的默认事件就是浏览器自己的行为,比如我们在点击<a href="#" target="_blank" rel="external nofollow" >的时候,浏览器跳转到指定页面。
语法部分
preventDefault() 方法
定义和用法
取消事件的默认动作。
语法
event.preventDefault()
说明
该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作)。例如,如果 type 属性是 "submit",在事件传播的任意阶段可以调用任意的事件句柄,通过调用该方法,可以阻止提交表单。注意,如果 Event 对象的 cancelable 属性是 fasle,那么就没有默认动作,或者不能阻止默认动作。无论哪种情况,调用该方法都没有作用。
代码部分:
实现效果:
7.参考文献
JavaScript事件处理的方式(三种):http://www.jb51.net/article/83052.htm
js事件机制:https://segmentfault.com/q/1010000006975586
8.更多讨论
Q1:事件冒泡有什么作用
A1:事件冒泡允许多个操作被集中处理
Q2:事件冒泡和事件捕获是什么?
A2:他们是描述事件触发时序问题的术语。事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。相反的,事件冒泡是自下而上的去触发事件。绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获。true,事件捕获;false,事件冒泡。默认false,即事件冒泡。
Q3:DOM0级事件与DOM2级事件的区别
A3:dom2级事件比起dom0级事件的好处就是,addEventListener() 增加多个dom事件,触发时都会依次发生,而DOM0级只能覆盖,不会连续触发。