JS高级程序设计读书笔记(第十三章 事件)

JavaScript与HTML之间的交互是通过事件实现的。

IE9,Firefox,Opera,Safari,Chrome全都已经实现了“DOM2级事件“模块的核心部分。IE8是最后一个仍然使用其专有事件系统的主要浏览器。
 

1 事件流

 
事件流描述的是从页面中接收事件的顺序。IE和Netscape开发团队提出差不多完全相反的事件流事件。
 

1.1 事件冒泡

 
IE的事件流叫做事件冒泡(even bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。所有现代浏览器都支持事件冒泡。
 

1.2 事件捕获

 
Netscape提出的事件流称为事件捕获(event capturing)。事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的事件应该最后接收到事件。
 

1.3 DOM事件流

 
“DOM2级事件“规定的事件流包括三个阶段:事件捕获阶段,处理目标阶段和事件冒泡阶段。即使“DOM2级事件“规范明确要求捕获阶段不会涉及事件目标,但IE9,Safari,Chrome,Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件,结果,就是会有两个机会在目标对象上面操作事件。
 

2 事件处理程序

 

2.1 DOM0级事件处理程序

 
通过JS指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。

var btn = document.getElementById('myBtn');
btn.onclick = function(){
    alert('Clicked');
}

以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。
 

2.2 DOM2级事件处理程序

 
DOM2定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener(),removeEventListener(),所有DOM节点都包含这两个方法,并且它们都接受3个参数:要处理的事件名,作为事件处理程序的函数和一个布尔值。最后一个布尔值参数如果为true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

其中,注意addEventListener(),removeEventListener()两个函数传入的必须是一个函数。并且大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种浏览器。

//跨浏览器的事件处理程序
var EventUtil = {

    addHandler : function(element, type, handler){
      if(element.addEventListener){
        element.addEventListener(type, handler, false);
      }else if(element.attachEvent){
        element.attachEvent('on'+type, handler);
      }
    },

    removeHandler : function(element, type, handler){
      if(element.removeEventListener){
        element.removeEventListener(type, handler, false);
      }else if(element.detachEvent){
        element.detachEvent('on'+type, handler);
      }
    }
  };

 

3 事件对象

 
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息,包括导致事件的元素,事件的类型以及其他与特定事件相关的信息。

无论指定事件处理程序时使用什么方法,都会传入event对象。event.type属性表示的是事件类型。

与访问DOM中的event对象不同,要访问IE中的event对象有几种不同的方式,取决于指定事件处理程序的方法。在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在;若是使用attachEvent(),那么就会有一个event对象最为参数被传入事件处理程序函数中。

var EventUtil = {

    addHandler : ......

    getEvent : function(event){
      return event ? event : window.event;
    }
  };

 

4 事件类型

 

4.1 UI事件

 

UI事件类型解释备注
load当页面加载后在window上面触发
select当用户选择文本框< input>或< texterea>中的一或多个字符时触发
error当发生JS错误时在window上面触发
resize当窗口或框架的大小变化时在window或框架上面触发
scroll当用户滚动带滚动条的元素中的内容时在该元素上面触发

 

4.1.1 scroll事件

 

在混杂模式下,可以通过body元素的scrollLeft和scrollTop来监控到这一变化;而在标准模式下,除Safari之外的所有浏览器都会通过html元素来监控这一反应(Safari仍然是基于body滚动的)

我的另外一篇博客也有讲到,点这里
 

4.1.2 焦点事件

 
这一类事件中最主要的两个就是focus和blur,所有的浏览器都支持这两个事件,但这两个事件的最大的问题就是它们不冒泡。
 

4.1.3 鼠标和滚轮事件

 
DOM3级事件中定义了9个鼠标事件

鼠标事件名称解释备注
click在用户单击鼠标按钮(一般是左边按钮)或者按下回车键时触发
dbclick在用户双击鼠标按钮(一般是左边按钮)
mousedown在用户按下任意鼠标按钮时触发
mouseenter在鼠标光标从元素外部首次移动到元素范围之内时触发这个事件不冒泡,而且光标移动到后代元素不会触发
mouseleave在位于元素上方鼠标光标移动到元素范围之外时触发同上
mousemove当鼠标指针在元素内部移动时重复地触发
mouseout在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发
mouseover在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发
mouseup在用户释放鼠标按钮时触发

 
只有在同一个元素上相继触发mousedown和mouseup事件,才会触发click事件。类似的,只有触发两次click事件才能触发一次dbclick事件。
 

4.1.3.1 客户区坐标位置

 
鼠标事件都是在浏览器视口中的特定位置上发生的。这个位置信息保存在事件对象的clientX和clientY属性中。所有浏览器都支持这两个属性。它们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标。注意:这个值不包括页面滚动的距离。

var myDiv = document.getElementById('myDiv');
EventUtil.addHandler(myDiv, 'click', function(){
    event = EventUtil.getEvent(event);
    alert('Client coordinate:'+ event.clientX + ","+event.clientY); 
  })

 

4.1.3.2 页面坐标位置

 
通过客户区坐标能够知道鼠标是在视口中什么位置发生的。而页面坐标通过事件对象的pageX和pageY属性,能够告诉你事件是在页面中什么位置发生的。

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

IE8及更早的版本不支持事件对象上的页面坐标,不过使用客户区坐标和滚动信息可以计算出来。

var myDiv = document.getElementById('myDiv');
  EventUtil.addHandler(myDiv, 'click', function(event){
    event = EventUtil.getEvent(event);
    var pageX = event.pageX,
        pageY = event.pageY;

    if(pageX == undefined){
      pageX = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
    }
    if(pageY == undefined){
      pageY = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
    }

    alert('page coordinates:' + pageX + ',' + pageY);
  })

 

4.1.3.3 屏幕坐标位置

 
通过screenX和screenY属性可以确定鼠标事件发生时鼠标指针相对于整个屏幕的坐标信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值