第13章 事件

13.1 事件流

事件流描述的是从页面中接收事件的顺序。

当浏览器发展到第四代时,浏览器开发团队遇到了一个很有意思的问题:页面的哪一部分会拥有某个特定事件?

针对这一个问题,IE提出了事件冒泡,Netscape提出了事件捕获

13.1.1 事件冒泡

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

13.1.2 事件捕获

即不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。

由于老版本的浏览器不支持,因此很少有人使用事件捕获。我们也建议大家放心的使用事件冒泡,在有特殊需要时再使用事件捕获。

13.1.3 DOM事件流

13.2 事件处理程序

响应某个事件的函数叫做事件处理程序,比如onclick

13.2.1 HTML事件处理程序



function showMsg(){
  
}

缺点:
(1) 存在时差问题。如果showMsg定位在页面最底部,用户在showMsg函数未解析之前点击按钮,会发生错误。
(2) 不同浏览器对其中作用域链理解不一样。
(3) html和js耦合太严重。

13.2 DOM0级事件处理程序

var btn = document.getElementById('myBtn');

btn.onclick = function(){
    alert(this.id);      //myBtn
}

使用DOM0级方法指定的事件处理程序被认为是元素的方法,因此,程序中的this引用当前元素。

13.2.3 DOM2级事件处理程序

即事件监听。使用addEventListener()和removeEventListener();

13.2.4 IE事件处理程序

事件监听。attachEvent() 和 detachEvent()

13.3 事件对象

即event,在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件有关的信息。

13.3.1 DOM中的事件对象。

在需要通过一个函数处理多个事件时,可以这样:

var btn = document.getElementById('myBtn');

var handler = function(event){
    
    switch(event.type){
       case "click":
           alert('Clicked');
           break;

       case 'mouseover':
           alert('mouseover');
           break;

       case 'mouseout':
           alert(mouseout);
           break;
    }
}

btn.onclick = handler;
btn.onmouseover = handler;
btn.mouseout = mouseout;

阻止默认行为:

event.preventDefault();

阻止冒泡

event.stopPropagation();

event.eventPhase 用来确定事件当前正位于事件流的哪个阶段。
1: 捕获阶段
2: 处于目标对象上
3: 冒泡阶段

13.4 事件类型

13.4.1 UI事件

指的是那些不一定与用户操作有关的事件

这些事件都与window对象有关

(1) load事件(图像,JS,CSS文件等都可以)

在相应对象上监听load事件即可

(2) unload事件
(3) resize事件
(4) scroll事件

13.4.2 焦点事件

(1) blur 在元素失去焦点时触发,这个事件不会冒泡。
(2) focus 在元素获得焦点时触发,这个事件不会冒泡。

13.4.3 鼠标与滚轮事件

(1) click
(2) dblclick
(3) mousedown 用户按下任意鼠标按钮时触发。不能通过键盘触发。
(4) mouseenter 鼠标光标从元素外部首次移动到元素范围之内时触发。这个事件不冒泡,而且在光标移动到后代元素上不会触发。
(5) mouseleave 在位于元素上方的鼠标光标移动到元素范围之内时触发。这个事件不冒泡,而且在光标移动到后代元素上不会触发。
(6) mousemove 当鼠标指针在元素内部移动时 重复 触发。
(7) mouseout 在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发。又移入的另一个元素可能位于前一个元素的外部,
也可能是这个元素的子元素。
(8) mouseover 在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发。
(9) mouseup 用户释放鼠标按钮时触发。

页面上所有元素都支持鼠标事件。除了mouseenter 和 mouseleave,所有鼠标事件都会冒泡,也可以被取消,而取消鼠标事件将会影响浏览器的默认行为。

1. 客户区坐标位置

以页面文档左上角为原点。
clientX:发生事件时鼠标指针在视口中的水平坐标
clientY:发生事件时鼠标指针在视口中的垂直坐标

2. 页面坐标位置

在页面没有滚动情况下,pageX和pageY的值与clientX和clientY的值相等

有滚动情况下:
pageY = 鼠标举例文档顶部距离 + 垂直滚动距离
clientY = 鼠标举例文档顶部距离

3. 屏幕坐标位置

鼠标事件发生时,不仅会有相对于浏览器窗口的位置,还有一个相对于整个电脑屏幕的位置

screenX和screenY

13.4.5 复合事件

13.4.7 HTML5事件

1. contextmenu 用以表示何时应该显示上下文菜单,以便开发人员取消默认的上下文菜单而提供自定义的菜单。

禁止默认行为,正常浏览器:event.preventDefault() IE:event.returnValue = false;

2. beforeunload 事件
3. DOMContentLoaded。在形成完整的DOM树之后就会触发,不理会图像,JS文件,CSS文件或其他资源是否已经下载完毕。

13.5 内存和性能

在js中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能。事实上,从如何利用好事件处理程序的角度出发,还是有一些方法能够提升性能的。

13.5.1 事件委托

当页面上很多元素需要触发同一事件时,可考虑使用事件委托来提高性能。



var list = $('#myLinks')
$(list).on('click', function(e){
   var target = $(e.target)[0];
   e.stopPropagation();

   switch(target.id){

    case 'doSomeWhere':
        alert('doSomeWhere');
        break;

    case 'doSomeThing':
        alert('doSomeThing');
        break;

    case 'sayHi':
        alert('sayHi');
        break;
   }
})

13.5.2 移除事件处理程序

解绑事件

13.6 模拟事件

13.6.1 DOM中的事件模拟

小结:

在使用事件时,需要考虑如下一些内存与性能方面的问题:

(1) 有必要限制一个页面中事件处理程序的数量,数量太多会导致占用大量内存,而且也会让用户感觉页面反应不灵敏。
(2) 建立在事件冒泡机制之上的事件委托技术,可以有效地减少事件处理程序的数量
(3) 建议在浏览器卸载页面之前移除页面中的所有事件处理程序。即解绑不用的事件处理程序。(btn.onclick = null)

你可能感兴趣的:(第13章 事件)