|
来看一下这个东西mousemat.html:
<html> <head> <link rel='stylesheet' type='text/css' href='mousemat.css' /> <script type='text/javascript'> var cursor=null window.onload=function(){ var mat=document.getElementById('mousemat'); mat.onmousemove=mouseObserver; cursor=document.getElementById('cursor');} function mouseObserver(event){ var e=event || window.event; writeStatus(e) drawThumbnail(e)} function writeStatus(e){ window.status=e.clientX+","+e.clientY} function drawThumbnail(e){ cursor.style.left=((e.clientX/5)-2)+"px"; cursor.style.top=((e.clientY/5)-2)+"px";}</script> </head> <body> <div class='mousemat' id='mousemat'></div> <div class='thumbnail' id='thumbnail'> <div class='cursor' id='cursor'></div> </div> </body> </html>
并附上还有要用到的mousemat.css
.body{ background-color: white;}.mousemat{ background-color: #ffe0d0; border: solid maroon 2px; width: 500px; height: 500px; top: 24px; left: 24px; position: absolute;}.thumbnail{ background-color: cyan; border: solid navy 1px; width: 100px; height: 100px; top: 24px; left: 528px; position: absolute; margin:0px; padding: 0px;}.cursor{ background-color: navy; width:3px; height: 3px; position: relative;}
试试看,什么效果,然后再继续下面的吧
下面的会是同样的效果,只是代码复杂了,当然下面的代码是不完整的,只是核心部分。
首先简单介绍下需要模拟的东西,在W3C新的事件模型框架中,IE和Mozilla都实现了相应的版本,在基于Mozilla的浏览器和Safari中,使用addEventListener()来附加时间按回调,使用相应的removeEventListener()来删除,IE提供了类似的函数:attachEvent()和detachEvetn()。在传统的javascript时间模型中,我们无法为一个元素注册多个事件(任何事件),如何解决?
恩,是的,只有靠自己来实现观察者模式了。下面的代码来自《ajax in action》,加入了注释及相关说明。
注:对于观察者模式(Observer)是设计模式的一种,可以查看资料。
//命名空间,是的,只是一种形式var jsEvent = new Array();//构造函数//其中的el在实际中表示的是页面的dom元素(可以是一个button元素,一个div元素等等等),eventType表示的是事件对象(如onclick等等等)jsEvent.EventRouter = function(el,eventType){ //内部维护一个事件列表,这里的lsnrs很重要,里面存放当事件发生时我们需要的执行事件,是一个数组,所以允许我们把很多事件放进去 this.lsnrs = new Array(); this.el = el; el.eventRouter = this; //给el元素(记住el是一个页面元素)添加属性eventRouter,这个属性是当前的EventRouter对象 //注册回调函数,恩,已经知道了前面的,现在可以翻译下下面这一句了 //类似于:el.onclick = jsEvent.EventRouter.callback;(后面只是一个当onclick事件发生时需要执行的事件函数而已,具体的callback是什么将在后面的代码中涉及) el[eventType] = jsEvent.EventRouter.callback;};//添加事件,使用了原型,注意添加在了哪里,是的,在上面那个构造函数里,什么用呢?答案是将需要在eventType(如onclick事件)发生时执行的动作事件放到lsnrs数组中,这里只是放进去,并没有执行。对于里面的执行的函数,下面也会说明,现在只是理清过程jsEvent.EventRouter.prototype.addListener = function(lsnr){ this.lsnrs.append(lsnr,true); } ;//移除事件,类似上面的增加事件jsEvent.EventRouter.prototype.removeListener = function(lsnr){ this.lsnrs.remove(lsnr); }; //通知所有事件,仍然看清楚这个属性函数加在了哪里,是的,还是在构造函数内,这个notify属性是真正执行、当事件发生时(如el元素被onclick)、需要执行的、被上面函数加在lsnrs数组中的、事件。这里用了奇怪的标点,只是为了不要产生误解jsEvent.EventRouter.prototype.notify = function(e){ var lsnrs = this.lsnrs; for(var i=0;i<lsnrs.length;i++){ var lsnr = lsnrs[i]; lsnr.call(this,e); }};//回调函数调用notify,看到了么,callback属性出现了,每当事件发生,都将调用notify函数,这样需要被执行的时间将被不断执行jsEvent.EventRouter.callback=function(event){ var e = event || window.event; var router = this.eventRouter; router.notify(e);};//下面的函数是用在addListener和removeListener中的,意思大家应该猜得出来了//直接在内建类array中增加原型,所有array类的对象都可以使用,其中obj是事件,当事件发生时需要执行的事件,obj对象需要有一个实现,而这里没有,nodup函数只是用来判断,当true时有效Array.prototype.append = function(obj,nodup){ if(nodup){ this[this.length]=obj; //为什么位置在this.length?恩,这里不明说了,自己动脑筋吧 }};//o表示当lsnrs数组中的一个元素,代表一个事件Array.prototype.remove = function(o){ var i = this.indexOf(o); if (i>-1) {this.splice(i,1); //这个函数的作用是:The splice() method is used to remove and add new elements to an array。splice(数组起始位置,删除元素个数,添加的新元素【0】,……,添加的新元素【n】),是的大概是这样的,这里的表示现在该清楚了吧 } return (i>-1); } };好了,如何使用上面的对象呢:var mat=document.getElementById('mousemat');cursor=document.getElementById('cursor');var mouseRouter=new jsEvent.EventRouter(mat,"onmousemove");mouseRouter.addListener(writeStatus); //这里面的事件嘛就需要自己写了mouseRouter.addListener(drawThumbnail); //这里也一样
当然这里的只是些核心代码,如果需要运行,当然还要增加一些必要的东西。那么就到此为止吧,codd和他的朋友们头痛了~~~~~~ |
|