JavaScript Event事件学习第一章 Event介绍

没有event就没有脚本。可以看看任何有JavaScript代码的网页:几乎所有的例子都有一个事件触发了脚本。原因非常简单。JavaScript就是给你的页面添加内部活动:用户做一些事情然后页面做出回应。

因此JavaScript就需要一个方法能够检测到用户的动作然后才能知道什么时候做出反应。这还需要知道那个函数会被执行,函数会做一些你认为的给你的网页增色的动作。这些文字描述了如何去写这样的脚本。虽然不容易,但是这是一个很让人满足的工作。

当用户做了什么事情event就发生了,当然还有一些event不会直接被用户触发:比如load事件会在页面装载完毕的时候触发。

JavaScript能够检测一些event。从Netscape 2开始,在HTML元素上添加event hanlder就成为可能。这些事件处理函数等待一个确定的事件,比如点击一个链接。当他发生的时候,事件就会通过你指定的JavaScript代码来执行。

当用户做出动作他就引发了一个事件。当你的代码让页面对这个动作做出回应,交互就产生了。

事件处理程序的历史

如上所述,没有事件处理程序就没有在页面添加JavaScript的必要。那些能对用户动作做出反应的就是最好的脚本。因此,当Netscape发布他的第二版支持JavaScript的浏览器的时候,他同时也支持event。

Netscape模式

Netscape只支持一小部分事件。Mouseover和mouseout的快速流行时因为当鼠标滑入时改变图片而滑出时又返回到原来的状态这个很炫的效果。而且可以看到用户是否提交了表单或者重置了表单,这样在客户端的验证也就成为了可能。浏览器还能监测表单的某一项获得或者失去了焦点或者页面完成下载又或者开始关闭。在如今看来这些都是非常稀松平常的事情,但在那个时候那可是革命性的。因为你能对用户的动作做出反馈,所以真正的交互才变成可能。

在最古老的表单的事件处理程序看起来是这样的。当用户点击了链接,事件处理程序就被执行了然后弹出对话框。

<a href="somewhere.html" onclick="alert('I\'ve been clicked!')">

注意到这种最古老的处理事件的方法事实上就是Netscape的标准是很重要的。如果想要JavaScript工作,其他的浏览器包括IE都得遵从Netscape 2和3的处理事件的标准。因此这些最古老的事件和事件处理程序在任何JavaScript浏览器中都能很好的运行。

现在的事件模式

然而,相比之前的介绍,现在的事件处理程序有了很大的变化。第一就是数量上急剧增长。对HTML元素的事件处理程序的注册的方法也有很大的变化。现在完全可由JavaScript设置。不再需要大量的附着于代码之上,你可以写一些很简单的代码来设置所有的事件处理程序。
V4浏览器也提供了关于事件的很多信息。鼠标在哪?什么时候事件发生?键盘按下了么?最终,浏览器必须要对一个元素和这个元素的父元素对同一个动作都有事件处理程序做出选择。哪个事件先触发呢?
因为这个功能而更加加剧了浏览器之间的战火,Netscape和微软制订了几乎互不兼容的两套事件模型。最近第三种模型开始显现,这是由w3c发布的DOM Event specification 。虽然有一个严重的缺陷,w3c模型是基于旧的Netscape模型但是更加的广义和通用,这是一份非常杰出的作品,添加了很多有趣的函数,也解决了一些老的事件模型存在的问题。
既然存在三种模型,所以事件处理程序也就不能以同样的方式在所有的浏览器里面运行。

浏览器的兼容性问题

我们继续。就像DHTML,w3c DOM或者其他高级的脚本技术一样,我们对于代买的每一个字节都要小心。在IE中使用stopPropagation()或者在Netscape中使用srcElement都会导致严重的错误而使我们的代码毫无用处。因此在使用方法或者属性之前我们必须对浏览器的支持性做必要的检查。
一个简单的代码片段如下:


代码如下:

if (Netscape) {
use Netscape model
}
else if (Explorer) {
use Microsoft model
}

这只是解决问题的一个开始而已。最近的浏览器能运行的事件处理程序的数量是巨大的,除非你的代码不允许除了Netscape或者IE其他少数浏览器运行。

所有的小众浏览器都必须不那么光彩的决定支持那种事件模型。Konqueror/Safari通常都选择严格的按照W3C的标准执行。Opera和iCab通常都会支持大部分的老的Netscape模型和一些微软的模型。我对其他的更小众的浏览器还没有做研究。

但是其他的更小众的浏览器可能选择支持微软处理事件的方法,同时又有W3C和老的Netscape的属性。这都没什么问题,总之他们都是以他们自己的方法支持我们知道的模型。你的代码应该没有问题。

不要使用浏览器类型检测

首先,永远永远都不要使用浏览器检测,这是通向地狱的捷径。任何代码如果使用navigator.userAgent来做事件模型的检测,那简直比没用还没用应该直接拉出去弹JJ。
第二,不要被DHTML的object detection的事件对象检测所迷惑。当你写DHTML的时候通常检测DOM的支持性,比如,if(document.all)。如果支持,那么代码如果使用Microsot的all容器就能搞很好的运行。
但是DHTML和事件处理程序有不同的浏览器兼容性模式。比如,Opera 6支持W3C DOM的一部分但是不支持W3C event模型。因此DHTML对象检测在Opera下会做出错误的决定。所以代码使用if(document.layers)或者其他的事件模型检测都是不正确的。

正确的问题

那么我们怎么办?Event属性的名字造成了这些问题。如果我们针对具体的对象探测使用不同的办法,基本上能解决99%的浏览器的不兼容问题。只有鼠标位置非常的麻烦,其他的都比较简单了。
另外,最好根本就不要去想那三个事件模型。实际上,我们应该去理解四种事件注册模型,两种事件执行模型和两种事件顺序。 这里可以快速查看下事件兼容性列表。
现在听起来好像非常的复杂,实际上并不是这样。当我们注意到这个的时候也就应该开始真正的理解事件处理程序了。这都是关于如何提出正确的问题的。不要问“我该怎么写事件处理程序的代码呢?”即使这是一个正确的问题,但是难以回答--那需要11页长的文章才能说清楚。因此你应该问那些有具体答案的具体问题:

“这里都有什么事件?”
“我怎么对一个HTML元素注册事件处理程序呢?”
“我怎么阻止默认动作的发生呢?”
“当我想要得到更多的信息的时候我怎么访问一个事件呢?”
“当我成功的触发了事件,我怎么读取他的属性呢?”
“如果一个元素和他的父元素对一个事件都有事件处理程序,那么谁先执行呢?”

上面所有的问题都会在单独的章节进行详细的解答。
写跨浏览器的事件处理程序的的技巧在于不要用整体的事件模型而是分别的回答每一个问题。你会发现,你只有在需要读出事件属性的时候才需要考虑浏览器的兼容性问题。
先选择一个事件注册模型,然后确定这个事件会在所有的浏览器里面触发,然后读出正确的属性,最后解决事件触发顺序问题-如果有的话。这样你就能分贝的解决浏览器兼容性问题也能确保你的代码能在所有的浏览器里良好的运行。

继续

如果你想按照顺序学习事件,你应该开始读下一章了。

写事件处理程序的代码

那么怎样写事件处理程序的代码呢?为了希望快速得到答案和打算以后再学习理论的童鞋,在这一章我会做一个简单的概述。

注册一个事件处理程序

第一步是先注册你的事件处理程序。你需要确定的是浏览器会在任何时候都执行你的代码。
这里有四种注册事件处理程序的方法:inline,traditional,w3c和Microsoft。
最好使用traditinal方法,因为他能很好的跨浏览器并且有很大的自由和通用性。注册一个事件处理程序,如下:


代码如下:

element.onclick = doSomething;
if (element.captureEvents) element.captureEvents(Event.CLICK);

现在这个函数doSomething()就注册成为一个HTML的element元素click事件的事件处理程序。这意味着无论什么时候用户点击了这个元素,那么doSomething()都会执行。

访问这个事件

但你注册了你的事件处理程序你就开始写真正的代码了。通常你想访问这个事件本身,所以你可以读取这个事件的信息。

访问这个事件所以你可以读出他的属性,通常你的事件处理程序开始如下:


代码如下:

function doSomething(e) {
if (!e) var e = window.event
// e refers to the event
}

现在e就表示在所有浏览器里面的事件,你也可以访问这个事件。

访问这个HTML元素

有时候你希望能够访问到发生事件的元素。这里有两个办法:使用this关键字或者使用target/srcElement属性。

比较保险的访问HTML元素的方法是使用this关键字。this并不总是指向正确的HTML元素,但是和traditional模式一起就能很好的工作。

代码如下:

function doSomething(e) {
if (!e) var e = window.event
// e refers to the event
// this refers to the HTML element which currently handles the event
// target/srcElement refer to the HTML element the event originally took place on
}

target/srcElement属性包含一个最初事件发生的HTML元素的引用。非常有用,但是当事件被捕获或者冒泡了他依然是那个最初发生事件的元素不会改变。

读取属性

在读出一些有趣的事件属性(event properties)这个问题上,是浏览器兼容最不好的部分。学习这个兼容性列表,然后写出你自己的代码来获取你需要的信息。
确定总是使用最仔细的对象检查。首先确定每一个属性是否存在,然后再读取他的值。比如:


代码如下:

function doSomething(e) {
if (!e) var e = window.event
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
}

现在code就包括了所按下的键,并且兼容所有的浏览器。

事件顺序

最后,你需要决定你是否希望事件冒泡。如果不希望发生事件冒泡,那么就阻止他:


代码如下:

function doSomething(e) {
if (!e) var e = window.event
// handle event
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
}

写代码
现在你可以开始写事件处理程序的代码了。通过前面的代码和信息,可以让你知道事件什么时候发生,你的代码应该做怎样的回应。记住:让交互更有逻辑性要么你的用户不会理解发生了什么。

(0)

相关推荐

  • JavaScript Event事件学习第一章 Event介绍

    没有event就没有脚本.可以看看任何有JavaScript代码的网页:几乎所有的例子都有一个事件触发了脚本.原因非常简单.JavaScript就是给你的页面添加内部活动:用户做一些事情然后页面做出回应. 因此JavaScript就需要一个方法能够检测到用户的动作然后才能知道什么时候做出反应.这还需要知道那个函数会被执行,函数会做一些你认为的给你的网页增色的动作.这些文字描述了如何去写这样的脚本.虽然不容易,但是这是一个很让人满足的工作. 当用户做了什么事情event就发生了,当然还有一些eve

  • JavaScript CSS修改学习第一章 查找位置

    offset 在所有的浏览器里面元素的offsetTop和offsetLeft两个属性都是很有用的.他们会给出你元素相对于父元素的坐标位置. 这段代码会向上查找offsetParent,然后添加offsetTop和offsetLeft.最终无论offsetParent在哪,他都会给出你元素在屏幕上的真正坐标. 解释 这段代码非常简单.先传入要计算的元素,然后设置变量curleft和curtop为0. 复制代码 代码如下: function findPos(obj) { var curleft =

  • JavaScript Event学习第二章 Event浏览器兼容性

    在这里提出的事件,当他们发生在一个确定的HTML元素上的时候,他们的名字能够被大多数的浏览器所识别.也就是说,浏览器会查找你为这个HTML元素所注册的事件处理程序的脚本,而且会被立即执行.      一开始只有为数很少的一些事件.这些事件在几乎所有的JavaScript浏览器都能运行,即使是那些非常古老的.需要注意的是那些早期的事件只能工作在链接或者表单上,有时候也能运行在整个窗口上,但是其他的大多数HTML元素不行.      时代变迁,很多新的事件也给大家介绍过了.第四代浏览器和更高级的浏览

  • JavaScript DOM学习第一章 W3C DOM简介

    在这一章我主要介绍已经被新一代的浏览器所支持的W3C 第一级的DOM.对他的运作做一个大概的了解并且让你知道你可以对他们做什么. 首先是对于DOM的一些建议和DOM设计的目的,然后我会告诉你什么是节点(nodes)并且怎样通过DOM树来遍历节点.接着是如何得到一个特定的节点,以及怎样改变他的值和属性.最后就是DOM的终极目标:怎么创建一个自己的新节点. 建议 Level 1DOM是W3C制定的用来提供给任何程序语言来访问XML文档的.不管你用什么语言程序来处理XML文档,只要是Level 1DO

  • JavaScript CSS修改学习第二章 样式

    另外,有时候你也许想知道添加到一个元素或者链接上的样式的具体内容.而style属性只能读取元素的内联形式的样式,所以如果你想读取其他样式就得另想办法了. 偏移 在使用一些小技巧之前,IE和Mozilla已经添加了一个比较好的办法:offsetSomething.使用这些属性你就能够读取这个段落现在的一些比较重要的样式. 举个例子,使用offsetWidth.你就能知道这个段落现在的宽度的像素值.为了测试,你可以改变一下窗口的大小然后再运行一下. 代码也非常的简单: 复制代码 代码如下: func

  • JavaScript阻止事件冒泡的方法

    我们需要注意的是:事件冒泡本身的特性,会带来的坏处,也会带来的好处,在后续的博客我会详细说明. 所以我们在这里将论述一下如何阻止事件冒泡. 比如现在有一个子盒子和一个父盒子,子盒子和父盒子二者都有点击事件,但是此时,当我们点击子盒子时,只想让子盒子显示点击事件.这里我们就要用到阻止事件冒泡的方法来隔断父盒子的事件显示. 先创建两个盒子,并给他们添加点击事件,如下所示: <!DOCTYPE html> <html lang="en"> <head> &

  • Javascript函数技巧学习

    目录 前言 1. 缓存函数 2. 将dev-point转换为devPoint 3. 自定义函数判断 4. JS运行环境 前言 阅读代码是提高编码水平的好方法,优秀的源代码就像一部文学巨作,开拓思维,提供启示.最近在阅读vue2的源代码,学到了很多JS的编码技巧,后续陆续分享出来供参考,顺便总结一下代码阅读成果. 1. 缓存函数 先来看一个需求,假设有一个逻辑复杂的函数 superComputed 执行很费时间,如果每次使用都去计算一次,就会给用户带来很长的等待.这个时候需要考虑将计算结果缓存起来

  • javaScript事件学习小结(四)event的公共成员(属性和方法)

    相关阅读: JavaScript事件学习小结(五)js中事件类型之鼠标事件 http://www.jb51.net/article/86259.htm JavaScript事件学习小结(一)事件流 http://www.jb51.net/article/86261.htm javaScript事件学习小结(四)event的公共成员(属性和方法) http://www.jb51.net/article/86262.htm JavaScript事件学习小结(二)js事件处理程序 http://www

  • JavaScript事件处理器中的event参数使用介绍

    在大部分浏览器中,当一个事件处理器被触发时,名为Event的类实例会作为第一个参数传入处理器中.而一直占据主流地位的ie却以自己专的方式行事,将Event实例保存到一个名为event的全局属性中. 复制代码 代码如下: if (!event) event=window.event; 上面的语句用来检测event参数是否为undefined或者null,如果是的话把window的event属性赋值给它,从而消除了浏览器差异. 为了获取目标元素的引用,在标准兼容的浏览器中使用target属性,在ie

  • JavaScript将DOM事件处理程序封装为event.js 出现的低级错误问题

    将 DOM 0级事件处理程序和DOM2级事件处理程序 IE事件处理程序封装为eventUtil对象,达到跨浏览器的效果.代码如下: var eventUtil = { // 添加事件句柄 addEventHandler:function (element,type,handler) { if (element.addEventListener) { element.addEventListener(type, handler,false); }else if(element.attachEven

随机推荐