资讯专栏INFORMATION COLUMN

JavaScript学习总结(九)事件详解

LiveVideoStack / 3003人阅读

摘要:布尔值表示捕获阶段调用事件处理程序,表示冒泡阶段通过对象的方法,也可以定义事件的回调函数。对象会被作为第一个参数传递给事件监听的回调函数。布尔默认值是,当设置成时用以取消事件的默认行为与中的相同。

其实这篇文章挺早之前就写了,但是由于sf保存方面的bug,所以当时写了一大堆,结果没保存,觉得这个没写完是个不小的遗憾,今天正好有空,就给补充下了,也正好给我的javascript学习总结做一个完结篇。

其实之前的文章也涉及到部分事件,可以参照我的文章:JavaScript学习总结(三)BOM和DOM详解

这里,主要讨论一下js相关的事件——

事件处理程序

DOM中定义了一些事件, 而响应某个事件的函数就叫事件处理程序(或事件侦听器)。事件处理程序的名字一般以“on”开头,例如:onclick

事件冒泡与捕获

事件流指的是页面中接收事件的顺序,IE,火狐和chrome浏览器都是事件冒泡,所谓是事件冒泡指的是事件最开始由最具体的元素接收,然后逐级向上传播到不具体的节点。而事件捕获则正好相反,事件捕获是由Netscape提出的,事件冒泡和捕获具体如下图所示:

虽然事件捕获是Netscape唯一支持的事件流模型,但目前IE9,火狐和谷歌也都支持这种事件流模型。

事件冒泡的好处

因为事件具有冒泡机制,因此我们可以利用冒泡的原理,把事件加到父级上,触发执行效果。这样做的好处当然就是提高性能了,


    
    
    


  • 1
  • 2
  • 3
  • 4

这样我们就可以做到li上面添加鼠标事件。但是如果说我们可能有很多个lifor循环的话就比较影响性能。
下面我们可以用事件委托的方式来实现这样的效果。html不变:


那么,如何阻止事件的冒泡呢,看下面一个例子:

点击黑色外围的效果图:

DOM 0级事件处理程序

通过js指定事件处理程序通常是将回调函数赋给这个事件处理程序的属性。每个元素都有自己的事件处理程序属性(属性小写,例如:onclick

btn.onclick = function(){
    console.log("hello");
};

使用DOM 0级指定的事件处理程序被认为是元素的方法。因此,this指向当前元素:

var btn = document.getElementById("myDiv");

//DOM上触发的事件会产生一个事件对象event
btn.onclick = function (event) {
    alert(this.id);//myDiv  
};


DOM level 1

DOM level 1 专注于 HTMLXML 文档模型。它含有文档导航和处理功能。

DOM level 1 于 1998 年 10 月 1 日成为 W3C 推荐标准。

第二版的工作草案在 2000 年 9 月 29 日。

值得一提的是:DOM level 0 并不是 W3C 规范。而仅仅是对在 Netscape Navigator 3.0IE 3.0 中的等价功能性的一种定义。

DOM 2级事件处理程序

DOM 2级定义了两个方法,用于指定和删除事件处理程序的操作:addEventListener()removeEventListener(),他们都接受三个参数:

1.事件名。比如上面的click
2.作为事件处理程序的函数。
3.布尔值(true表示捕获阶段调用事件处理程序,false表示冒泡阶段)

通过Element对象的addEventListener方法,也可以定义事件的回调函数。

//element.addEventListener(event, function, useCapture) 

var btn = document.getElementById("myDiv");
btn.addEventListener("click", function () {
    console.log(this.id);
},false);
IE中的事件处理程序

IE9之前的IE浏览器不支持addEventListener()removeEventListener()
与其他浏览器不同的是,IE使用的是attachEvent()detachEvent()方法来为DOM添加事件处理程序,由于IE8及更早版本只支持事件冒泡,所以他们只接受两个参数:

1、事件处理程序名称(前面要加on)
2、事件处理程序函数

使用attachEvent()添加的事件处理程序如下:

var btn = document.getElementById("myDiv");
btn.attachEvent("onclick", function () {
    console.log(this.id);
});

值得注意的是,使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,所以,此时this等于window

事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件相关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。event对象会被作为第一个参数传递给事件监听的回调函数。我们可以通过这个event对象来获取到大量当前事件相关的信息:

type (String) — 事件的名称
target (node) — 事件起源的DOM节点
currentTarget?(node) — 当前回调函数被触发的DOM节点(后面会做比较详细的介绍)
bubbles (boolean) — 指明这个事件是否是一个冒泡事件(接下来会做解释)
preventDefault(function) — 这个方法将阻止浏览器中用户代理对当前事件的相关默认行为被触发。比如阻止元素的click事件加载一个新的页面
cancelable (boolean) — 这个变量指明这个事件的默认行为是否可以通过调用event.preventDefault来阻止。
stopPropagation (function) — 取消事件的进一步捕获或冒泡,bubbles为true使用这个方法
eventPhase:返回一个数字,表示事件目前所处的阶段,0为事件开始从DOM表层向目标元素传播,1为捕获阶段,2为事件到达目标元素,3为冒泡阶段。

此外,事件对象还可能拥有很多其他的属性,但是他们都是针对特定的event的。比如,鼠标事件包含clientXclientY属性来表明鼠标在当前视窗的位置。

另外,stopPropagation()方法用于立即停止事件在DOM中的传播,即取消进一步的事件冒泡或捕获。

var btn = document.getElementById("myDiv");
btn.onclick = function (event) {
    alert("clicked");
    event.stopPropagation();
};

//避免触发在document.body上的事件处理程序
document.body.onclick = function (event) {
    alert("Body clicked");  
};

只有在事件处理程序执行期间,event对象才会存在,一旦事件处理程序执行完毕,event对象就会自动销毁。

IE中的事件对象

DOM 0级中添加事件处理程序时,event对象是作为window对象的一个属性存在的:

var btn = document.getElementById("myDiv");
btn.onclick = function (event) {
    var event = window.event;
    alert(event.type);//click
};

IE 的event对象同样也包含与创建它的事件相关的属性和方法。

cancleBubble 布尔   默认值时false,但可以被设置成true来取消事件冒泡,与dom中的 stopPropagation()方法相同。
returnValue  布尔    默认值是true,当设置成false时用以取消事件的默认行为 与dom中的preventDefault()相同。
srcElement  元素    事件的目标,与dom中的target属性相同。
type     字符串   被触发的事件类型。 
click事件

当用户点击以后,event对象会包含以下属性。

pageX,pageY:点击位置相对于html元素的坐标,单位为像素。
clientX,clientY:点击位置相对于视口(viewport)的坐标,单位为像素。
screenX,screenY:点击位置相对于设备显示屏幕的坐标,单位为设备硬件的像素
clientX,clientY

图示:clientXclientY,他们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标(不包含滚动条区域)

偏移量

   通过以下4个属性可以取得元素的偏移量。

   (1)offsetHeight:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。

   (2)offsetWidth:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度和右边框宽度。

   (3)offsetLeft:元素的左外边框至包含元素的左内边框之间的像素距离。

   (4)offsetTop:元素的上外边框至包含元素的上内边框之间的像素距离。 
pageX,pageY

这两个属性表示鼠标光标在页面中的位置,在页面没有滚动的情况下,pageXpageY的值与clientXclientY的值相等

滚动大小

滚动大小,指的是包含滚动内容的元素的大小。

   以下是4个与滚动大小相关的属性。

   (1)scrollHeight:在没有滚动条的情况下,元素内容的总高度。

   (2)scrollWidth:在没有滚动条的情况下,元素内容的总宽度。

   (3)scrollLeft:被隐藏在内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动位置。

   (4)scrollTop:被隐藏在内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置。 
焦点事件

焦点事件会在页面元素获得或失去焦点时触发,有以下4个焦点事件:

 1. blur:元素失去焦点时触发,该事件不冒泡
 2. focus:元素获得焦点时触发。不冒泡
 3. focusin:元素获得焦点时触发,冒泡
 4. focusout:元素失去焦点时触发,冒泡
鼠标事件

DOM 3级定义了9个鼠标事件:

click:当用户点击鼠标主键通常是指鼠标左键或按回车键时触发。

dbclick:用户双击鼠标时触发

mousedown:当用户按下鼠标任意一个键都会触发,这个事件是不能够通过键盘触发的。

mousemove:当鼠标在某元素周围移动时重复触发,该事件不能通过键盘事件触发。

mouseout:当鼠标离开元素时触发,这个事件不能通过键盘触发。

mouseover:当鼠标进入元素时触发,这个事件不能够通过键盘触发。
 mouseenter:类似“mouseover”,但不冒泡,而且当光标移到后代元素上不会触发。 

mouseleave:类似“mouseout”,但不冒泡。在元素上方是不触发。

mouseup:当用户释放鼠标按键时触发,不能够通过键盘触发。


传递给鼠标事件处理程序的事件对象有clientX和clientY属性,它们指定了鼠标指针相对于包含窗口的坐标。加入窗口的滚动偏移量,就可以把鼠标位置转换成文档坐标。

  页面上的所有元素都支持鼠标事件。除了mouseentermouseleave外,所有的事件都冒泡,并且他们的默认行为是可以被取消掉的。但取消鼠标事件的默认行为可能会影响到其他事件,因为有些鼠标事件是相互依赖的。

mouseentermouseover的不同:
http://www.w3school.com.cn/ti...
拖拉事件

(1)drag事件

drag事件在源对象被拖拉过程中触发。

(2)dragstartdragend事件

dragstart事件在用户开始用鼠标拖拉某个对象时触发,dragend事件在结束拖拉时触发。

(3)dragenterdragleave事件

dragenter事件在源对象拖拉进目标对象后,在目标对象上触发。dragleave事件在源对象离开目标对象后,在目标对象上触发。

(4)dragover事件

dragover事件在源对象拖拉过另一个对象上方时,在后者上触发。

(5)drop事件

当源对象被拖拉到目标对象上方,用户松开鼠标时,在目标对象上触发drop事件。
相关文章

JavaScript学习总结(一)基础部分

JavaScript学习总结(二)数组和对象部分

JavaScript学习总结(三)BOM和DOM详解

JavaScript学习总结(四)function函数部分

JavaScript学习总结(五)原型和原型链详解

JavaScript学习总结(六)数据类型和JSON格式

JavaScript学习总结(七)Ajax和Http状态字

JavaScript学习总结(八)正则表达式

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85393.html

相关文章

  • Flutter 面试知识点集锦

    摘要:中的的线程是以事件循环和消息队列的形式存在,包含两个任务队列,一个是内部队列,一个是外部队列,而的优先级又高于。同时还有处理按住时的事件额外处理,同时手势处理一般在的子类进行。谷歌大会之后,有不少人咨询了我 Flutter 相关的问题,其中有不少是和面试相关的,如今一些招聘上也开始罗列 Flutter 相关要求,最后想了想还是写一期总结吧,也算是 Flutter 的阶段复习。 ⚠️系统完...

    andong777 评论0 收藏0
  • 详解js闭包

    摘要:但闭包的情况不同嵌套函数的闭包执行后,,然后还在被回收闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗。每个函数,不论多深,都可以认为是全局的子作用域,可以理解为闭包。 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 闭包的特性 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变量不会...

    Chiclaim 评论0 收藏0
  • JavaScript学习总结(三)BOM和DOM详解

    摘要:有级级级共个级别。事件类型事件类型鼠标事件键盘事件事件事件处理器执行代码的程序在事件发生时会对事件做出响应。在标签中使用事件处理器的语法是标签事件处理器代码事件处理程序事件就是用户或浏览器自身执行的某种动作。 DOM介绍 D(文档)可以理解为整个Web加载的网页文档,O(对象)可以理解为类似window对象只来的东西,可以调用属性和方法,这里我们说的是document对象,M(模型)可...

    littlelightss 评论0 收藏0
  • 前端基础进阶():详解面向对象、构造函数、原型与原型链

    摘要:我们通过一个简单的例子与图示,来了解构造函数,实例与原型三者之间的关系。而原型对象的指向构造函数。于是根据构造函数与原型的特性,我们就可以将在构造函数中,通过声明的属性与方法称为私有变量与方法,它们被当前被某一个实例对象所独有。 showImg(https://segmentfault.com/img/remote/1460000008593382); 如果要我总结一下学习前端以来我遇...

    Tony_Zby 评论0 收藏0

发表评论

0条评论

LiveVideoStack

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<