MooTools中的事件(中)
我们在《MooTools中的事件(上)》中介绍了MooTools的事件类型, 并把MooTools中的事件分为5大类:窗口事件 (Window Events),
表单元素事件 (Form Element Events),键盘事件 (Keyboard Events),鼠标事件 (Mouse Events),MooTools自定义事件。本节所介绍的是MooTools 事件的添加(addEvent() 和 addEvents()),移除(removeEvent() 和 removeEvents()),克隆(cloneEvents()),指定(fireEvent())等有用的方法。
MooTools支持HTML 4.01里的所有的事件属性。
You can read the official W3C specifications on events in the
HTML 4.01 Specification, section 18.2.3, under Intrinsic
events: http://www.w3.org/TR/html401/interact/scripts.html#h-18.2.3
JavaScript和HTML之间的交互是通过用户与浏览器中的页面操作时引发的事件来处理的,我们以前是用传统的JavaScript事件处理方式,为了兼容各种主流的浏览器,我们需要写事件处理兼容性函数。
不过有了MooTools以后我们就不用担心我们的事件处理了,它扩展了所有的基本事件处理方式。MooTools的事件处理语法格式非常通俗易懂,便于阅读,不过也因此较为累赘,而jQuery的简洁让我不知道在干什么,这是我个人比较偏好于MooTools程式的可阅读性,不过那是主观的看法。
了解更多:
The domready event listener(加载DOM)
使用JavaScript操纵DOM,必须等待DOM加载完毕才可以执行代码,但window.onload有个坏处,它非要等到页面中的所有图片及视频加载完毕才会触发load事件。结果就是一些本来应该在打开时隐藏起来的元素,由于网络延迟,在页面打开时仍然会出现,然后又会突然消失,让用户觉得莫名其妙。甚至在图片加载之前就执行了需要依赖的元素的脚本而导致脚本错误.我们想做的就是经常想要执行的代码更快,提高Web应用程序的响应速度。寻找一种方法来确定DOM被完全的加载时不用等待所有那些讨厌的图片加载完毕的解决方法。想要了解JavaScript原始的解决方案就看《关于window.onload加载的多种解决方案 》文章中的第七种方案。
其实MooTools已经提供了window对象的自定义事件: ‘domready’ 。 MooTools就是用window.addEvent(‘domready’, function() {})方式来代替传统JavaScript的window.onload 方法的。
- 该事件在页面的DOM树加载完成后触发.
- 在需要保证所要操作的DOM元素已经加载完成的情况,本事件将非常有用.
- 本事件只对window对象有效.
语法如下:
1 2 3 | window.addEvent('domready', function() { alert('Hello World'); }); |
在这个代码块,我们使用了addEvent()方法来监听’domready’事件,来告诉我们Window’s DOM 是否准备就绪,一旦DOM已准备好了,我们就绑定一个事件处理器函数执行相应的方法:
1 2 3 | function() { alert("Hello World"); } |
默认的情况下所有的代码都应该包含在‘domready’事件监听下。
window.onload方法 与 ‘domready’事件 的区别:
- 执行时机不同。(window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行,即JavaScript此时才可以访问网页中的任何元素。而通过MooTools 的 ‘domready’事件注册的事件处理函数,在DOM完全就绪时就可以被调用。)
- 使用次数不同。(window.onload方法多次调用会导致相冲突。MooTools 的 ‘domready’事件可以多次监听,根据监听的顺序依次执行对应的事件处理函数。)
- 支持的浏览器不同。(window.onload方法只支持IE和FF,MooTools中的‘domready’事件支持所有的主流浏览器。)
使用次数不同的例子:
1 2 3 4 5 6 7 8 9 | //执行一次 function firstFunction(){ alert("hello firstFunction !"); } function secondFunction(){ alert("hello secondFunction !"); } window.onload=firstFunction; window.onload=secondFunction; |
执行后的结果是:只弹出secondFunction()的对话框字符串。
1 2 3 4 5 6 7 8 9 10 11 12 | //多次执行方法一 function firstFunction(){ alert("hello firstFunction !"); } function secondFunction(){ alert("hello secondFunction !"); } window.onload=function(){ firstFunction(); secondFunction(); } |
执行后的结果是:依次弹出firstFunction()和secondFunction()的对话框字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ////多次执行方法二 function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { oldonload(); func(); } } } //测试 addLoadEvent(firstFunction); addLoadEvent(secondFunction); |
执行效果同上。
MooTools的通用方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //DOM完全就绪时就可以处理监听事件;可以多次使用,依次执行动作;支持所有的主流浏览器。 function firstFunction(){ alert("hello firstFunction !"); } function secondFunction(){ alert("hello secondFunction !"); } window.addEvent('domready', function() { firstFunction(); }); window.addEvent('domready', function() { secondFunction(); }); |
MooTools的‘load’事件和window.onload()方法的作用一样:
1 2 3 4 5 6 7 8 9 | //JavaScript的window.onload()方法 window.onload = loadFunction; function loadFunction(){ alert("hello!"); } //MooTools的‘load’事件 window.addEvent('load', function() { alert("hello!"); }); |
Adding event listeners(添加事件监听器 / addEvent())
我们要添加事件监听到一个网页上使用addEvent()和addEvents()两大方法。这样我们可以为每一个匹配元素的特定事件(像click)绑定一个事件处理器函数。
Adding a single event listener(添加一个事件监听器)
在文档完成后,如果向一个元素添加一个事件监听器的方法是:addEvent()方法。
语法如下:
1 | $(yourelement).addEvent(event, function(){}); |
第一个参数是事件类型,包括:
1 2 3 4 5 6 7 8 9 | Element.NativeEvents = { click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons mousewheel: 2, DOMMouseScroll: 2, //mouse wheel mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement keydown: 2, keypress: 2, keyup: 2, //keyboard focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form elements load: 1, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window error: 1, abort: 1, scroll: 1 //misc }; |
例如,在以下代码块中,我们监听了所有的<a>元素的点击事件。在任何时候只要用户点击我们网页上的超链接,它就会运行一个函数,并弹出一个警告对话框 ,说“你点击一个超链接!”。
1 2 3 4 5 | window.addEvent('domready', function() { $$('a').addEvent('click', function(event) { alert('You clicked on a hyperlink!'); }); }); |
基本效果:在网页表单中突出重点的文本字段
下面我们通过实例来了解addEvent()方法的用法。
The MooTools JavaScript
1 2 3 4 5 6 7 | window.addEvent('domready', function(){ var els = $$('input, textarea') els.addEvent('focus', function(){ els.removeClass('focused'); this.addClass('focused'); }) }); |
Adding multiple event listeners(添加多个事件监听器 / addEvents())
addEvents()方法允许您添加多个事件监听到一个元素(或元素的集合)。
语法如下:
1 2 3 4 | $(yourelement).addEvents({ 'event1' : function {}, 'event2' : function {} }) |
让我们继续探讨前面的网页表单例子,看一下我们是如何使用addEvents()方法的。
The MooTools JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | window.addEvent('domready', function(){ $('feedback').setStyle('opacity', 0); $$('input, textarea').addEvent('focus', function(){ $$('input, textarea').removeClass('focused'); $(this).addClass('focused'); }); // 初始化helptext 数组,存储帮助文本 var helptext = []; //帮助内容 helptext['hName'] = 'Enter your first and last name'; helptext['hEmail'] = 'Enter a valid email address'; helptext['hWebsite']='Enter a valid website url'; helptext['hComment'] = 'Leave your feedback'; // 给 span.help 添加事件 $$('.help').addEvents({ 'mouseover' : function() { $('feedback').tween('opacity', 1); // 获得 span's 的 ID spanID = $(this).get('id'); // 设置 feedback div 的内容 //使用spanID 索引数组 $('feedback').set('html', helptext[spanID]); }, 'mouseout' : function() { $('feedback').tween('opacity', 0); } }); }); |
上面的例子也许不太好,我再举一个例子,比较通用一些。在我们的留言,登录和查询模块中,我们很喜欢给表单的文本字段(input) 加上默认输入值,这一微妙的改进,是非常有利于用户体验的,当我们点击进入该字段域时,默认输入值就给人一种消失的感觉,当你离开该域的时候该字段为空,再点击别的域的时候,该域又恢复了默认输入值。
Framework Independent Javascript / 原始的做法
1 | <input name="s" id="s" size="20" value="Search" alt="Search Box" onfocus="if(this.value == 'Search') { this.value = ''; }" onblur="if(this.value == '') { this.value = 'Search'; }" type="text" /> |
The MooTools JavaScript :
1 2 3 4 5 6 7 | window.addEvent('domready',function() { var t = $('s'); t.addEvents({ 'focus': function() { t.value = (t.value == 'search...' ? '' : t.value); }, 'blur': function() { t.value = (t.value == '' ? 'search...' : t.value); } }); }); |
表单的文本字段默认值 – 例子演示
Creating custom events(创建自定义事件)
MooTools 的灵活性之一就是可以自由的扩展,我们也可以创建自己的自定义事件。我们只需要给 Element.Events 对象扩展相应的属性就可以自定义事件了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Element.Events.eventname = { 'base' : 'click', // A base event such as click, keypress,keydown, onload, etc. 'condition' : function() { // conditions that need to be met to trigger event }, 'onAdd' : function() { // Functions to trigger when you bind/add the event to elements }, 'onRemove' : function() { // Functions to execute when you unbind/remove elements } }; |
eventname: 这是自定义事件的名称。
自定义一个事件时, Element.Events.eventname中可包含如下内容:
- base – (string, 可选) 自定义事件所监听的基类事件. 如果指定了下面condition参数,则本参数必须填写
- condition – (function, 可选) 自定义事件触发的条件函数 (函数的参数为一个Event实例)
- onAdd – (function, 可选) 当元素添加自定义事件时触发的函数 (函数的参数为一个Event实例)
- onRemove – (function, 可选) 当元素删除自定义事件时触发的函数 (函数的参数为一个Event实例)
创建一个自定义的事件。
MooTools custom event “outerClick”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | Element.Events.outerClick = { base : 'click', /*event.stopPropagation()该方法将停止事件的传播,阻止它被分派到其他 Document 节点。 在事件传播的任何阶段都可以调用它。 注意,虽然该方法不能阻止同一个 Document 节点上的其他事件句柄被调用, 但是它可以阻止把事件分派到其他节点。 */ condition : function(event){ event.stopPropagation();// stop event bubbling to the body return false;// never run handler when clicking on element }, /*getDocument() return this.ownerDocument;*/ onAdd : function(fn){ this.getDocument().addEvent('click', fn); }, onRemove : function(fn){ this.getDocument().removeEvent('click', fn); } }; window.addEvent('domready',function(){ $$('a').addEvent('outerClick', function(){ alert("ok");}); }); |
MooTools 自定义’outerClick’ 事件 的 演示
MooTools 框架提供的自定义事件:
我们可以自己创建自定义事件的同时,MooTools 框架也 提供了三个非常有用的自定义事件:
- mouseenter
- 本事件在鼠标进入指定元素区域时触发,并且不会在鼠标穿越子元素的时候再次触发(区别于mouseover)。
- mouseleave
- 本事件在鼠标离开指定元素区域时触发,并且不会再离开本元素的子元素的时候触发(区别于mouseout)。
- mousewheel
- 本事件在鼠标滚轮滚动时触发。
The MooTools JavaScript :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | window.addEvent('domready', function(){ /*JavaScript原生的鼠标事件:mouseover , mouseout , mousemove*/ $('parent').addEvents({ //当鼠标指针悬停于某元素之上时执行脚本 'mouseover':function(event){ $('print').set('html','mouseover, '+'X:' + event.client.x + ' Y:' + event.client.y); }, //当鼠标指针移出某元素时执行脚本 'mouseout':function(event){ $('print').set('html','mouseout, '+'X:' + event.client.x + ' Y:' + event.client.y); }, //当鼠标指针移动时执行脚本 'mousemove':function(event){ $('print').set('html','mousemove, '+'X:' + event.client.x + ' Y:' + event.client.y); } }); /*MooTools扩展的自定义事件:mouseenter , mouseleave , mousewheel */ $('parent1').addEvents({ //mouseenter 鼠标进入DOM元素的区域后触发。不会在经过子元素的时候触发(不像 mouseover)。 'mouseenter':function(event){ $('print1').set('html','mouseenter, '+'X:' + event.client.x + ' Y:' + event.client.y); }, //mouseleave 鼠标离开DOM元素的区域后触发。不会在经过子元素的时候触发(不像 mouseout)。 'mouseleave':function(event){ $('print1').set('html','mouseleave, '+'X:' + event.client.x + ' Y:' + event.client.y); }, //本事件在鼠标滚轮滚动时触发 'mousewheel':function(event){ $('print1').set('html','mousewheel, '+'X:' + event.client.x + ' Y:' + event.client.y); } }); /*mouseenter 和 mouseleave 的综合应用 */ $('parent2').addEvents({ 'mouseenter': function(){ this.set('tween', { duration: 1000, transition: Fx.Transitions.Bounce.easeOut }).tween('height', '200px'); }, 'mouseleave': function(){ this.set('tween', {}).tween('height', '20px'); } }); }); |
Custom Events 与 mousewheel 事件 的 实例演示
更多的 MooTools事件类型介绍请看:《 MooTools中的事件(上) 》
Removing, cloning, and firing off events (移除, 克隆 ,指定 等事件方法)
除了我们上面讲到的添加事件监听器的方法以外,有的时候我们还需要其它的操作,你可能需要移除一个元素事件,克隆其它元素的事件 , 触发元素上指定的事件等的操作。接下来我们就来了解这些事件处理方法。
Removing a single event from elements (从元素上移除一个单一事件 / removeEvent() )
有两种方法可以移除元素上的事件。首先是removeEvent() 方法,它移除了一个指定的事件。
The MooTools JavaScript :
1 2 3 4 5 6 7 8 9 10 11 | document.addEvent('domready', function(){ //创建一个 function object var warning = function() { alert('You have clicked a link. This is your only warning'); //警告后,并会删除网页上所有的<a>元素 $$('a').removeEvent('click', warning); }; //添加单击事件监听器,并执行 warning 方法 $$('a').addEvent('click', warning); }); |
正如我们运行以后,点击链接所看到的,单击一次以后,所有的 ‘click’ 事件被移除了,再次点击也不会有单击事件被触发。
Removing a type of event, or all events, from elements (从元素上移除一个事件或者所有的事件 / removeEvents() )
如果你想删除一个元素的事件类型(或一组元素的事件类型),或者删除所有的事件,你必须使用removeEvents()方法。
移除元素上所有的事件:
1 | $('myElement').removeEvents(); |
移除元素上所有的 ‘click’ 事件:
1 | $('myElement').removeEvents('click'); |
Cloning events from another element(复制目标元素上的所有事件到本元素 / cloneEvents() )
如果你想克隆另一个元素的所有事件到本元素吗?这可能是有益的情况下,我们会这样做的,我们知道克隆一个元素使用的是 MooTools 的 clone() 方法;不过它只是克隆元素,并没有克隆附加的事件到本元素,所以你还必须使用cloneEvents() 来克隆目标元素上的所有事件到本元素 。
The MooTools JavaScript:
1 2 3 4 5 6 | // 克隆元素 var original = $('originalElement'); var myClone = original.clone(); //复制目标元素上的所有事件到本元素 myClone.cloneEvents(original); |
同上
1 2 | var myElement = $('myElement'); var myClone = myElement.clone().cloneEvents(myElement); //复制元素并复制下所有的事件 |
Firing off events (触发元素上指定的事件类型 / fireEvent() )
有的时候,我们要给某些元素指定一些事件类型。如指定一个事件由另一个事件触发。例如,下面的例子,你会做以下操作:
The MooTools JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | document.addEvent('domready', function(){ // Add a click event $$('a').addEvent('click', function(){ alert('You either clicked a link or pressed the Ctrl key.'); }); // Add a keydown event on our web page document.addEvent('keydown', function(e){ // If the keypress is the Ctrl key // manually fire off the click event if(e.control) { $$('a').fireEvent('click'); } }); }); |
The MooTools JavaScript:
1 2 | //触发myElement的click事件,并在一秒钟后执行事件的监听函数(向每个函数传入anElement元素作为参数) $('myElement').fireEvent('click', $('anElement'), 1000); |
到这里我《MooTools中的事件(中)》部分已经讲完了。下一节我们会关注MooTools 的事件对象(event object)。
Nice ! I am becoming a fan of your tutorials. Simple but detailed. Concise but explanatory. Keep up the good work !
我会努力的,谢谢!!!