概念
事件是您在编程时零碎内产生的动作或者产生的事件,零碎响应事件后,如果须要,您能够某种形式对事件做出回应。
在 Web 中, 事件在浏览器窗口中被触发并且通常被绑定到窗口外部的特定局部 — 可能是一个元素、一系列元素、被加载到这个窗口的 HTML 代码或者是整个浏览器窗口。
事件流
事件流形容的是页面中承受事件的程序。
“DOM2级事件“规定的事件流包含三个阶段:事件捕捉阶段、处于指标阶段和事件冒泡阶段。——《JavaScript高级程序设计》
依据W3C模型,事件首先被指标元素所捕捉,而后向上冒泡。——《基于MVC的JavaScript Web富利用开发》
事件捕捉
从顶层的父节点开始触发事件,从外到内流传,到触发事件originTarget完结。
事件冒泡
从内层originTarget节点开始触发事件,由外向外流传,逐级冒泡直到顶层节点完结。
留神:不是所有的事件都反对事件冒泡的,blur、focus、load、unload、mouseenter、mouseleave以及自定义事件不反对冒泡。
阻止事件流传
e.stopPropagation()
:大家常常听到的可能是阻止冒泡,实际上这个办法不只能阻止冒泡,还能阻止捕捉阶段的流传。e.stopImmediatePropagation()
:阻止监听同一事件的其余事件监听器被调用。如果多个事件监听器被附加到雷同元素的雷同事件类型上,当此事件触发时,它们会按其被增加的程序被调用。如果在其中一个事件监听器中执行stopImmediatePropagation(),那么剩下的事件监听器都不会被调用。
阻止事件默认行为
e.preventDefault()
能够阻止事件的默认行为产生,默认行为是指:点击a标签就转跳到其余页面、拖拽一个图片到浏览器会主动关上、点击表单的提交按钮会提交表单等等,因为有的时候咱们并不心愿产生这些事件,所以须要阻止默认行为。
留神:
- 只有cancelable属性为true的事件才能够应用preventDefault()办法来勾销其默认行为
- 既要终止冒泡又要阻止默认行为时,间接
return false
即可
事件处理器(事件监听器)
用来响应事件的函数或代码块
事件处理程序HTML属性(内联事件处理程序)
属性值就是当事件产生时要运行的JavaScript代码
<input id="btn" type="button" onclick="handleClick(this.value)" value="hello"/><script> function handleClick(value){ console.log(window.event); console.log(event); console.log(event.target); console.log('this', this); // window console.log(value); // hello console.log(this.value); // undefined }</script>
通过这种形式指定时,会创立一个封装着元素属性值得函数。这个函数中有一个局部变量event(即事件对象)。通过event变量,能够间接拜访事件对象,你不必本人定义它,也不必从函数的参数列表中读取(经测试,在chrome、和IE11中不必从函数的参数列表读取,然而在fireFox中则须要)。在这个函数外部,this值等于事件的指标元素。——《JavaScript高级编程》
下面这段话咱们能够了解为:通过html属性指定事件处理程序时,在指定的处理函数外再包装一层函数,而后将这个新函数赋值给btn.onclick(见DOM0级事件处理程序),这样新函数作用于内的this就指向了事件指标元素。然而在具体的事件处理函数handler外部,因为没有 具体的调用对象,在非严格模式下它外部的this指向window
DOM0级事件处理程序
var btn = document.getElementById("btn");btn.onclick = function() { alert(this.id); // btn}
DOM2级事件处理程序
次要就是addEventListener
和removeEventListener
两个办法,它们都承受3个参数:要解决的事件名、事件处理函数、一个布尔值(示意是否启用事件捕捉),应用它们的次要益处就是能够增加多个事件处理程序。
留神:如果监听的函数是匿名函数,没有任何援用指向它,在不销毁这个元素的前提下,这个监听是无奈被移除的。
IE事件处理程序(IE7、IE8)
IE实现了attachEvent()和detachEvent()。这两个办法都承受两个参数:事件处理程序名称和事件处理函数。
- 在应用这两个函数时,事件处理程序会在全局作用域中运行,因而this指向window
- 这些事件处理程序不是以增加它们的形式运行的,而是以相同的程序触发
跨浏览器的事件处理程序
function addHandler(target, eventType, handler) { if (target.addEventListener) { // DOM2 Events target.addEventListener(eventType, handler, false); } else if (target.attachEvent) { // IE target.attachEvent('on' + eventType, handler); } else { target['on' + eventType] = handler; }}function removeHandler(target, eventType, handler) { if (target.removeEventListener) { target.removeEventListener(eventType, handler, false); } else if (target.detachEvent) { target.detachEvent('on' + eventType, handler); } else { target['on' + eventType] = null; }}// 阻止事件 (次要是事件冒泡,因为IE不反对事件捕捉)function stopPropagation(e) { if (e.stopPropagation) { e.stopPropagation(); // 规范w3c } else { e.cancelBubble = true; // IE }}// 勾销事件的默认行为function preventDefault(e) { if (e.preventDefault) { e.preventDefault(); // 规范w3c } else { e.returnValue = false; // IE }}
事件委托
艰深来讲,就是把一个元素响应事件(click、keydown等)的函数委托到另一个元素。
通常会把一个或一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到须要绑定的元素上时,会通过事件冒泡机制触发。
自定义事件
非IE浏览器
形式一
// 创立事件,参数为事件类型var event = new Event('Event'); // 初始化事件// initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void;event.initEvent('build', true, true); elem.addEventListener('build', function(e) { // do something}, false);// 触发事件elem.dispatchEvent(event);
形式二
Event的构造函数定义为new(type: string, eventInitDict?: EventInit): Event;
其中EventInit的定义为:interface EventInit { bubbles?: boolean; // 是否冒泡,默认false cancelable?: boolean; // 是否可勾销,默认false composed?: boolean; //是否是否会在shadow DOM根节点之外触发侦听器,默认false}
// 创立及初始化事件var event = new Event('build', { bubbles: true, cancelable: true});elem.addEventListener('build', function(e) { // do something}, false);// 触发事件elem.dispatchEvent(event);
IE8及之前浏览器
var event = document.createEventObject(); // 不承受任何参数// 给event的属性赋值...elem.fireEvent('onclick', event); // 触发事件
在调用fireEvent()
办法时,会主动为event对象增加srcElement
和type
属性;其余属性则都是必须通过手工增加的。
事件对象
事件对象分为DOM中的事件对象和IE中的事件对象,应该是为了兼容,Event对象的中的属性和办法将这两种事件对象的属性办法都包含进去了。
DOM中事件对象的属性/办法
bubbles: boolean
表明事件是否冒泡cancelable: boolean
表明是否能够勾销事件默认行为composed: boolean
是否是否会在shadow DOM根节点之外触发侦听器currentTarget: EventTarget
以后正在调用事件处理函数的那个元素defaultPrevented: boolean
为true示意曾经调用了preventDefault()办法eventPhase: number
调用事件处理程序的阶段:1示意捕捉阶段,2示意“处于指标”,3示意冒泡阶段isTrusted: boolean
表明是否是浏览器生成的事件target: EventTarget
事件的指标initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void;
preventDefault(): void
stopImmediatePropagation(): void
stopPropagation(): void
type: string
事件类型
IE中的事件对象的属性/办法
cancelBubble: boolean
默认值为false,但将其设置为true就能够勾销事件冒泡returnValue: boolean
默认值为true,但将其设置为false就能够勾销事件的默认行为srcElement: Element
事件的指标,对应targettype: string
事件类型(IE中的type与DOM中的type是雷同的)
留神:target
和currentTarget
的区别