事件流

事件流描述的是从页面中接收事件的顺序。
先捕获后冒泡

事件冒泡

IE —— 事件冒泡 —— 事件开始时最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
例:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Event Bubbling Example</title>
  5. </head>
  6. <body>
  7. <div id="myDiv">Click me</div>
  8. </body>
  9. </html>

如果单击页面中的

元素,那么这个 click 事件会按照如下顺序传播:

  1. document
  • 取消冒泡:
    • w3c 标准 event.stopPropagation(); 但不支持 ie9 以下版本
    • IE 独有 event.cancelBubble = true;
    • 封装取消冒泡的函数 stopBubble(event)
  • 阻止默认事件:
    • 默认事件——表单提交,a 标签跳转,右键菜单等
    • return false; 以对象属性的方式注册的事件才生效
    • event.preventDefault(); W3C 标注,IE9 以下不兼容
    • event.returnValue = false; 兼容 IE
    • 封装阻止默认事件的函数 cancelHandler(event);

      事件捕获

      Netscape —— 事件捕获 —— 不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到节点

以上面的例子为例的话,单击

元素就会以下列顺序触发 click 事件

  1. document

DOM2级 规定的事件流包括三个阶段:先捕获,再处于目标阶段,最后事件冒泡。

事件处理程序

事件处理程序即响应某个事件的函数。事件处理程序的名字以 on 开头,因此 click 事件的事件处理程序就是 onclick 。

HTML 事件处理程序

某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的 HTML 特性来指定。
例子:

  1. <input type="button" value="Click me" onclick="alert('clicked')" />

缺点

  1. 时差问题。用户可能会在 HTML 元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件。
  2. 扩展事件处理程序的作用域链在不同浏览器中会导致不同结果。
  3. HTML 与 JavaScript 代码紧密耦合

DOM0 级事件处理程序

通过 JavaScript 指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。
每个元素(包括 window 和 document)都有自己的事件处理程序属性,这些属性通常全部小写,例如 onclick 。将这种属性的值设置为一个函数,就可以指定事件处理程序。

  1. var btn = document.getElementById("myBtn");
  2. btn.onclick = function() {
  3. alert("clicked");
  4. }
  5. btn.onclick = null; // 删除事件处理程序

使用 DOM0 级方法指定的事件处理程序被认为是元素的方法 。即 this 指向的是 DOM 元素本身。
以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。

删除通过 DOM0 级方法指定的事件处理程序。

  1. btn.onclick = null;

DOM2 级事件处理程序

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

  1. 要处理的事件名
  2. 事件处理函数
  3. true:捕获;false:冒泡 ```javascript var btn = document.getElementById(“myBtn”); var handler = function() { alert(this.id); } btn.addEventListener(“click”, handler, false);

btn.removeEventListener(“click”, handler, false);

  1. this 指向的是 DOM 元素本身<br />好处:可以添加多个事件处理程序
  2. <a name="1AWHu"></a>
  3. ## IE事件处理程序
  4. IE 独有。<br />`attachEvent()` `detachEvent()` 。这两个方法接受相同的参数:事件处理程序名称与事件处理程序函数。<br />由于 IE8 及更早版本只支持事件冒泡,所以通过 `attachEvent()` 添加的事件处理程序都会被添加到冒泡阶段。
  5. ```javascript
  6. var btn = document.getElementById("myBtn");
  7. var handler = function() {
  8. alert("clicked");
  9. }
  10. btn.attachEvent("onclick", handler);
  11. btn.detachEvent("onclick", handler);

this 指向 window 。

跨浏览器的事件处理程序

自己编写保证处理事件的代码能在大多数浏览器下一致地运行,只需关注冒泡阶段。
addHandler() 方法接受 3 个参数:要操作的元素、事件名称和事件处理程序函数。

  1. var EventUtil = {
  2. addHandler: function(element, type, handler) {
  3. if (element.addEventListener) {
  4. element.addEventListener(type, hander, false);
  5. } else if (element.attachEvent) {
  6. element.attachEvent("on" + type, handler);
  7. } else {
  8. element["on" + type] = handler;
  9. }
  10. },
  11. removeHander: function(element, type, handler) {
  12. if (element.removeEventListener) {
  13. element.removeEventListener(type, handler, false);
  14. } else if (element.detachEvent) {
  15. element.detachEvent("on" + type, handler);
  16. } else {
  17. element["on" + type] = null;
  18. }
  19. }
  20. };

事件对象

事件对象即 event 对象

DOM中的事件对象

target 和 currentTarget 属性:this 始终等于 currentTarget 的值,而 target 则只包含事件的实际目标。
type 属性:被触发的事件的类型。

阻止特定事件的默认行为,可以使用 preventDefault() 方法。
只有 cancelable 属性设置为true的事件,才可以使用 preventDefault() 来取消其默认行为。

  1. var link = document.getElementById("myLink");
  2. link.onclick = function(event) {
  3. event.preventDefault();
  4. };

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

eventPhase 属性,可以用来确定事件当前正处于事件流的哪个阶段。如果是在捕获阶段调用的事件处理程序,那么 eventPhase 等于 1 ;如果事件处理程序处于目标对象上,则 eventPhase 等于 2 ;如果是在冒泡阶段调用的事件处理程序, eventPhase 等于 3 。这里要注意的是,尽管“处于目标”发生在冒泡阶段,但 eventPhase 仍然一直等于 2 。

IE中的事件对象

在使用 DOM0 级方法添加事件处理程序时, event 对象作为 window 对象的一个属性存在。

  1. var btn = document.getElementById('myBtn');
  2. btn.onclick = function() {
  3. var event = window.event;
  4. alert(event.type); // 'click'
  5. }

DOM 中的 event.target 等于 IE 中的 window.event.srcElement
returnValue 属性相当于 DOM 中的 preventDefault() 方法,它们的作用都是取消给定事件的默认行为。只要将 returnValue 设置为 false ,就可以阻止默认行为。
cancelBubble 属性与 DOM 中的 stopPropagation() 方法作用相同,都是用来停止事件冒泡的。由于 IE 不支持事件捕获,因为只能取消事件冒泡;但 stopPropagation() 可以同时取消事件捕获和冒泡

跨浏览器的事件对象

  1. event = event | window.event;
  2. target = event.target | event.srcElement;
  3. prventDefault: function(event) {
  4. if(event.preventDefault) {
  5. event.preventDefault();
  6. } else {
  7. event.returnValue = false;
  8. }
  9. }
  10. stopPropagation: function(event) {
  11. if(event.stopPropagation) {
  12. event.stopPropagation();
  13. } else {
  14. event.cancelBubble = true;
  15. }
  16. }
  17. addHandler: function(element, type, handler) {
  18. if(element.addEventListener) {
  19. element.addEventListener(type, handler, false);
  20. } else if (element.attachEvent) {
  21. element.attachEvent("on" + type, handler);
  22. } else {
  23. element["on" + type] = handler;
  24. }
  25. }

事件类型

UI事件

当用户与页面上的元素交互时触发

  • load :当页面完全加载后在 window 上面触发,当所有框架都加载完毕时在框架集上面触发,当图像加载完毕时在 事件 - 图1 元素上面触发,或者当嵌入的内容加载完毕时在 元素上面触发。
  • unload
  • abort
  • error
  • select
  • resize
  • scroll

    焦点事件

    当元素获得或失去焦点时触发

  • blur:在元素失去焦点时触发。不会冒泡。

  • focus:在元素获得焦点时触发。不会冒泡。
  • focusin:在元素获得焦点时触发。冒泡。
  • focusout:在元素失去焦点时触发。

    鼠标事件

  • click :在用户单击主鼠标按钮(一般是左边的按钮)或者按下回车键时触发。DOM的button属性可能有如下3个值:0表示主鼠标按钮,1表示中间的鼠标按钮(鼠标滚轮按钮),2表示次鼠标按钮。

  • dblclick :在用户双击主鼠标按钮(一般是左边的按钮)时触发。
  • mousedown :在用户按下了任意鼠标按钮时触发。
  • mouseenter :在鼠标光标从元素外部首次移动到元素范围之内时触发。不会冒泡。
  • mouseleave:在位于元素上方的鼠标光标移动到元素范围之外时触发。不会冒泡。
  • mousemove:当鼠标指针在元素内部移动时重复地触发。
  • mouseout:在鼠标指针位于一个元素上方,然后用于将其移入另一个元素时触发。(相关元素:relatedTarget)
  • mouseover:在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素之内时触发。(相关元素:relatedTarget)
  • mouseup:在用户释放鼠标按钮时触发。
  • 滚轮事件
    • mousewheel:当用户通过鼠标滚轮与页面交互、在垂直方向上滚动页面时(无论向上还是向下),就会触发mousewheel事件。
  • contextmenu:右键事件。
  • 只有在同一个元素上相继触发 mousedown 和 mouseup 事件,才会触发 click 事件。
    客户区坐标位置: clientXclientY ,相对于浏览器窗口
    页面坐标位置: pageXpageY ,相对于页面
    在页面没有滚动的情况下,pageXpageY 的值与 clientXclientY 的值相等。
    屏幕坐标位置:screenXscreenY ,相对于整个电脑屏幕

    修改键:

    • event.shiftKey
    • event.ctrlKey
    • event.altKey
    • event.metaKey

    event属性wheelDelta属性。当用户向前滚动鼠标滚轮时,wheelDelta是120的倍数;当用户向后滚动鼠标滚轮时,wheelDelta是-120的倍数。
    Firefox支持一个名为DOMMouseScroll的类似事件。而有关鼠标滚轮的信息则保存在detail属性中,当向前滚动鼠标滚轮时,这个属性的值是-3的倍数,当向后滚动鼠标滚轮时,这个属性的值是3的倍数。

    键盘与文本事件

    文本事件,当在文档中输入文本时触发

    键盘事件

    • keydown :当用户按下键盘上的任意键时触发,而且如果按住不放的话,会重复触发此事件。
    • keypress :当用户按下键盘上的字符键时触发,而且如果按住不放的话,会重复触发此事件。按下 Esc 键也会触发这个事件。
    • keyup :当用户释放键盘上的键时触发。
    • text Input:用户在可编辑区域中输入字符时触发。

    按键的顺序:

    • keydown
    • keypress
    • keyup

    keydown 和 keypress 都是在文本框发生变化之前被触发的;而 keyup事件则是在文本框已经发生变化之后被触发的。

    keydown 和 keypress的区别

    • keydown 可以响应任意键盘按键,keypress 只可以响应字符类键盘按键
    • keypress 返回 ASCII 码,可以转换成响应字符
    • 字符类按键且要区分大小写用 keypress

    事件对象中的属性:

    • 键码:keyCode
      • 回车:13
    • 字符编码:charCode ,只有在发生 keypress 事件时才包含值
    • 相应键的名:key
    • char:在按下字符键时的行为与key相同,但在按下非字符键时值为null
    • location:一个数值,表示按下了什么位置上的键:0表示默认键盘,1表示左侧位置,2表示右侧位置,3表示数字小键盘,4表示移动设备键盘(也就是虚拟键盘),5表示手柄。(不推荐使用)

    复合事件

    当为IME(Input Method Editor,输入法编辑器)输入字符时触发

    变动事件

    当底层DOM结构发生变化时触发

    事件委托

    • 利用事件冒泡,和事件源对象进行处理
    • 优点:
      • 1.性能 不需要循环所有的元素一个个绑定事件
      • 灵活 当有新的子元素时的不需要重新绑定事件