概念
事件是您在编程时零碎内产生的动作或者产生的事件,零碎响应事件后,如果须要,您能够某种形式对事件做出回应。
在 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
的区别