ExtJS 2.2事件机制(详细)

来源:互联网 发布:大数据分析需要多少人 编辑:程序博客网 时间:2024/04/27 13:25
ExtJS事件机制是ExtJS架构体系中核心部分。它不但扩展浏览器Dom元素事件,使其兼容于各大主流浏览器,而且它采用观察者模式的来架构组件的事件机制,为组件提供了良好的扩展性。

本章从浏览器事件讲起,结合浏览事件机制来阐述ExtJS对其扩展。对于组件事件机制,我们将剖析其实现并结合实例来应用它。最终让读者能深入地了解和应用整个ExtJS事件机制。
本章主要内容:
ExtJS元素事件
ExtJS组件事件
ExtJS事件应用

4.1 浏览器事件机制
什么是事件呢?事件是一个对象所发生的事。当我们单击一个HTML元素时,就会触发一个onclick的事件。一般来说事件都是程序无法预知某个操作何时发生,但是发生又要进行相关的处理。这个处理的工作就是浏览器的事件机制来完成。

浏览器的事件机制有两种模型,一是最基本的原始事件模型,它是一种简单的事件模型,第二种是就是标准事件模型,这是强大而且有完整特性的事件模型。2级DOM标准对它进行了标准化。与标准事件模型相对应的IE事件模型,因为IE浏览器并没有完整地实现标准事件模型,而是用自行的事件模型。

原始事件模型可以通过嵌入处理代码到HTML标签和赋值到元素的事件属性中来进行注册事件的处理工作。而标准模型是采用是addEventListener(IE采用attachevent)来为元素增加事件处理函数。下面我们通过一个例子来演示并说明事件的注册及相关的特性:
<a id="test1" style="cursor:hand;"  href="http://www.sina.com.cn"  

onclick="alert('direct:'+id);">test1,click me!</div>

<script type="text/javascript">

    //  代码处

</script>

这是一个在body中简单的测试,我们想注册一个事件,其最原始的方式就是直接在其HTML标签中对应的事件属性中写上可运行的JS代码。在上面的代码中,我们给a标签的click事件编写了处理语句。它就是弹出direct: test1值。

在这里,我们直接通过id来取到当前标签(dom元素)的属性值,对于直接使用其属性名就可以取值看起来有点奇怪,但是我们可以把onclick中的代码看作是被with(this){//alert(id)}包裹的代码,这样就可以直接引用当前对象的属性。其实这个this作用域不仅仅是当前标签(dom元素),如果当前标签中id不存在,它会找到上一层元素的id属性(不同浏览器的实现不同,见javascript权威教程)。

在原始事件模型中还可以通过元素事件属性来注册处理函数。我们只要在代码4.1中注释的代码处加上如下代码:
var n=document.getElementById('test1');

n.onclick= function {  alert('attribute:'+this.id); };


这样我们实现了原始事件模型的第二种注册事件函数的方法。它是先找到a标签构建的DOM元素对象。之后在这个对象的onclick属性上赋上一个回调数函数。当点击该链接时就会调用这个注册的处理函数。

这种方法和直接嵌入处理代码也还是有点区别的,一它是回调函数形式,而不是代码。二回调函数被调用时,会自动传入event的参数(兼容于DOM0DOM2的事件的浏览器。IE不会传入)。同时该回调函数的作用域(即this)也会改变指向当前运行的对象,这里是a标签对应的DOM对象。也就说明在事件的回调函数中可以通过this来动态引用运行它的当前对象的方法或属性,如这里的this.id。

我们现在运行一下,发现会弹出attribute:test1内容。但是只运行了一次,然是注册两次,为什么呢?在原始事件模式中,每个事件只能注册一个处理函数。第二次注册的回函数取代了在HTML注册的函数。接下来我们通过标准事件模型来创建,在上面的代码后面加上下面的代码:
function addEvent(elem,type,fn){

if (elem.addEventListener) elem.addEventListener(type, fn,false);

elseif (elem.attachEvent)  elem.attachEvent("on" + type, fn);  }

function  clickme1(e){ alert('normal1:'+this.id); }

function  clickme2(e){ alert('normal2:'+this.id); }

  addEvent(n,'click',clickme1);

addEvent(n,'click',clickme2);

对于标准事件模型,IE的实现并不完全相同(一般称为IE事件模型),这里的addEvent就是屏蔽它们的创建方式的不同。在标准事件模型中,是通过元素的addEventListener来创建,它的第一个参数是事件名(也就是去标签事件属性前缀on,如onclick—>click)。第二个参数是事件的处理函数。第三个参数设定是否采用捕获的机制,因为IE不支持,所以一般都设为false。IE是通过元素的attachEvent来创建,它的第一个参数是就是事件属性名,不要去掉前缀on。第二个参数是要注册的函数。

接下来就是通过这个addEvent为a标签注册一个处理。我们先运行一下,发现和它现在会三次弹出内容,然后转到href指定的地址上去。在这里,它并没有覆盖原始事件模型中注册的回调函数。标准事件模型会把通过原始事件模型注册的函数作为它的注册函数集合中的一个处理函数(没有顺序)。并且会向它传入event对象(IE中通过window来获取)。

但是在标准模型中注册的函数中,其中this.id得到值是undefined,这里的函数的作用域和原始事件注册函数是不同的,它的作用域不再是当前运行它的对象,而是定义它的对象,这里的this指向window,所以返回undefined。

对于a标签,它有一个默认是动作,就是跳转到href指定地址,该动作发生在所有注册事件函数执行完成之后,那么如果想取消这个动作呢,对于click事件,它可以在最后运行的注册函数中返回false来取消。我们可以把returnfalse;加在上面三个注册的事件函数中任何一个的后面,它都取消默认的动作。因为在标准事件在调用中,会保存上一次的设定的返回状态。如果其它处理函数没有显式地设定值,那么就采用它做为返回值,精确地讲是采用最后一次显式设定的返回值作为整个事件的返回值。Jquery的trigger中事件处理就和它相似。

对于标准模型中采用return false来阻止默认动作的运行,在IE中可以完成任务,但是在FF中就不能阻止了。因为标准模型是采用专门的函数来进行阻止,而IE模型是在标准和原始模型之间。那么我们把代码4.3中clickme2改成如下的代码:
function  clickme2(e) {    

e=e||window.event;

alert('normal2:'+this.id);

if(e.preventDefault)    e.preventDefault();

    else     e.returnValue = false;

     }

首先在原来的基础之上加上e=e||window.event,那是因为IE事件模型中,它的Event不是传递给事件处理函数,而是存放在window对象event属性中。在alert后面,是我们用来进行阻止默认动作的代码,如果是标准模型,那么就会有preventDefault函数,就直接调用它。上面我们也讲了对于IE模型,我们采用设定其返回值false就会阻止默认的动作。那个返回值是通过回调函数来返回,并存在在event的returnValue属性中。这里我们是直接把其存在event的returnValue属性中。

这个例子是讲了浏览器三种注册处理函数的方法和区别,对于浏览器,它还有fireEvent,removeEvent等处理,在下一节将进行讲解。通过这个例子,我们可以了解掌握浏览器事件的基本应用,同是也看到不同的浏览器的事件处理不太相同,为了解决这个问题,ExtJS就进行了扩展,让其兼容起来。在下一节中,我们来详细地介绍事件的流程和机制并结合ExtJS的对它进行的扩展进行讲解。
0 0
原创粉丝点击