浏览器事件对象详解

来源:互联网 发布:马踏棋盘 栈 贪婪算法 编辑:程序博客网 时间:2024/04/30 16:44

客户端js程序采用了异步事件驱动模型,每当我们点击或敲击键盘时,浏览器就会产生事件,如果js程序关注特定类型的事件,那么它可以注册当这类事件发生时要调用的一个或多个处理函数。这种风格并不止应用于web编程,所有使用图形用户界面的应用程序都采用了它。它们等待事件发生,然后它们响应。
事件类型(event type)是一个用来说明发生什么类型事件的字符串,例如mouseover表示用户移动鼠标,keydown表示键盘上某个按键被按下。
事件目标(event target)是发生的事件或与之相关的目标。
事件处理程序(event handler)或事件监听程序(event listener)是处理或响应事件的函数。当在特定的目标上发生特定类型的事件时,浏览器会调用对应的处理程序,当对象上注册的事件处理程序被调用时,我们有这样几种等价的说法: 浏览器触发(fire,trigger)或者派发(dispatch)了事件。
事件对象(event object)是与特定事件相关并且包含有关该事件,事件对象作为参数传递给事件处理函数。
事件传播(event propagation)是浏览器决定哪个对象触发其事件处理程序的过程。对于单个对象的特定事件(比如window对象的load事件),必须是不能传播的。当文档元素上发生某个类型的事件时,他们会在文档树上向上传播或冒泡。有时在容器上注册单个事件处理程序比在每个独立的目标上都注册处理程序要更方便。(在容器上注册处理程序只是改变事件处理函数,并不能改变触发的元素,触发的元素正常都是最底层元素)。
事件传播的另一种形式成为事件捕获(event capturing),在容器上注册的特定处理程序有机会在事件传播到真实目标之前拦截它。

事件对象坐标

事件对象的坐标包括clientX和clientY,screenX和screenY, offsetX和offsetY,
pageX和pageY,X和Y。
clientX和clientY是相对于浏览器(可视区左上角的0, 0)的坐标
screenX和screenY是相对于设备屏幕左上角(0,0)的坐标
offsetX和offsetY是相对于事件源左上角(0,0)的坐标
pageX和pageY是相对于整个网页左上角(0,0)的坐标
X和Y 本来是IE属性,相对于用CSS动态定位的最内层包容元素。

表单事件

当提交表单和重置表单时,< form>元素会分别触发submit和reset事件,当用户和类表单元素交互时,它们会发生click事件。当用户通过输入文字,选择选项或选择复选框来改变相应表单元素的状态时,这些通常维护某种状态的表单元素会触发change事件。对于文本输入域,只有用户和表单元素完成交互并通过Tab键或单击的方式移动焦点到其他焦点到其他元素上才会触发change事件(然而在React中,每次进行文本输入都会出发change事件)。响应通过键盘改变焦点的表单元素在得到和失去焦点时会分别出发focus和blur事件

Window事件

Window事件是指事件的发生与浏览器窗口本身而非窗口中显示的任何特定文档内容相关,但是,这些事件中有一些会和文档元素上发生的事件同名.
load事件是这些事件中最重要的一个,当文档和其所有外部资源(比如图片)完全加载并显示给用户时就会触发它。
unload事件和load相对,当用户离开当前文档转向其他文档时会触发它。
window对象的onerror属性有点像事件处理程序,当js出错时会触发它。
像img元素也可以为load和error事件注册处理程序,当外部资源完全加载或加载错误的时候就会触发它们。H5支持abort事件,当图片或其他网络资源因为用户停止加载进程而导致失败就会触发它
当用户调整浏览器大小或滚动它时会触发resize和scroll事件。scroll事件也可以在任何可以滚动的元素上触发,比如那些设置CSS的overflow属性为scroll的元素

鼠标事件

对于click事件,detail属性指定了其是单击,双击或三击,clientX和clientY属性指定了鼠标在窗口坐标中的位置
用户每次移动或拖动鼠标时,会触发mousemove事件,这些事件的发生非常频繁,所以mousemove事件处理程序一定不能触发计算密集型任务。
在mousedown和mouseup事件队列之后,浏览器也会触发click事件。悬停和移走会触发mouseover(不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件,只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件)和mouseout事件。
keydown和keyup事件是低级键盘事件。当keydown事件产生可打印的字符时,在keydown和keyup之间会触发另外一个keypress事件

HTML5事件

HTML5的拖放API提供了很多拖放事件,具体可以参考实现H5的拖放 。HTML5定义了历史管理机制,它允许web应用同浏览器的返回和前进按钮交互(pushState)。HTML5提供了解决跨域问题的message事件,也提供了storage事件来监听数据的本地存取。

触摸屏和移动设备事件

旋转移动设备产生的orientationchange事件,手势开始时生成gesturestart事件,而手势结束时生成gestureend事件,在两个事件之间是跟踪手势过程的gesturechange事件。如果想实现自定义手势,可以监听touchstart事件和touchmove事件。

注册事件处理程序

最简单的方式就是通过on + 事件名称注册事件回调处理函数。这种方法兼容性好,缺点是围绕每个事件目标对于每种事件类型最多只能有一个事件处理程序(有多个文档时或引用多个依赖时会出现重写的问题)

addEventListener

addEventListener不影响on绑定的事件处理,同时它能注册多个处理函数

   function fn1(){      alert('fn1');   }   function fn2(){      alert('fn2');   }   function fn3(){      alert('fn3');   }   var btn = document.getElementById('button');   btn.onclick = fn1;   //第三个参数false为事件冒泡,true为事件捕获   btn.addEventListener('click', fn2, false);   btn.addEventListener('click', fn3, false);   //点击连续弹出3个弹窗(按顺序)   //使用removeEventListener为处理函数解绑   btn.removeEventListener('click', fn3, false);

IE8及其以下浏览器不支持这两个函数,IE中有类似的函数attachEvent(以这个函数注册的处理顺序可能按照任何顺序调用),所以需要封装一个兼容函数

事件处理程序的运行环境

在事件处理程序内,this关键字指的是事件目标。而使用attachEvent注册的事件处理函数,this的指向是window,所以要在其中使用call或者apply来改变this指向。

事件处理函数的作用域

事件处理函数的作用域是定义时的作用域(经常通过闭包获得外部变量)。但是通过HTML属性注册事件处理程序是一个例外,他们被转换成能存取全局变量的顶级函数而非任何本地变量

事件处理程序的返回值

通常情况下,返回值false是告诉浏览器不要执行这个事件相关的默认操作,例如表单提交按钮的onclick事件处理函数返回false就能组织浏览器提交表单。如果用户输入不合适的字符,输入域上的onkeypress事件处理就能通过返回false来过滤键盘输入。返回false的兼容性很好。

事件传播

在调用在目标元素上注册的事件处理函数之后,大部分事件会冒泡到DOM树根,调用目标的父元素的事件处理程序,然后调用在目标的祖先元素上注册的事件处理程序。事件冒泡为大量单独文档元素上注册程序提供了更好的方案,即在共同的祖先元素上注册一个处理程序来处理所有的事件。例如可以在< form>元素上注册change事件来取代表单上每个元素上的每个元素上注册change事件处理程序。还有像选项卡中要获取li的索引,可以通过直接在ul上注册事件,然后通过事件的target来判断是哪一个li被点击了
事件冒泡是事件传播的第三个阶段,目标对象本身的事件处理程序调用是第二个阶段,第一个阶段发生在目标处理程序调用之前,成为捕获阶段,事件捕获只能通过addEventListener 注册,这意味者事件捕获在IE8之前无法使用。

事件取消

在支持addEventListener 的浏览器中,也能通过调用事件对象的preventDefault()方法取消事件的默认操作。在IE9之前的IE中,可以通过设置事件对象的returnValue为false来达到相同的效果。下面假设一个事件处理程序,通过能力检测来判断浏览器支持程度

   function cancelHandler(event){       //省略其他处理       //window.event用于IE       var event = event || window.event;       if(event.preventDefault) event.preventDefault();       //IE       if(event.returnValue) event.returnValue = false;       return false;          }

使用stopPropagation 之后,除了在同一个对象上定义的其他事件处理函数,其他对象上的事件处理程序将不会被调用。IE9之前的IE不支持stopPropagation,IE有一个cancelBubble属性,设置为true可以达到相同效果

0 0
原创粉丝点击