JavaScript注册机的实现(类似于观察者模式)

      前言:本人由于工作经验有限,把自己一下想法写出来给大家分享下,欢迎园子里各路牛人的板砖拍过来。
      之前一直在做一个webgis的前端开发,用到了诸如ajax,WS等等技术。在项目结束后,自己的总结过程中,有了一个对javaScript 控制事件触发的模型的概念,这段时间有拜读了下设计模式中的观察者模式,总算是有了些成熟的想法。
       这些想法是我在做B/S的底层地图控制的时候的一些想法,比如一个用户在移动地图的同时会触发多个事件,但是这个触发的事件是动态的。在之前的老办法就是通过全局变量来控制,但是用全局变量的话,程序的可控制性太差,一点改动就会引起其他地方的改动,这个缺点在后期的维护的时候尤其明显。所有就有了这个思考的结果。
       废话不多说,直接上代码:
                         
      上面的截图是我用来做的测试界面,整体的想法是:用一个注册机实现多个事件的同时触发,并用这个注册机去控制当前注册的事件。如上图所示,举例假设一共有三个待注册的事件,用一个注册机的对象来实现对这触发三个事件的控制。
链表类:
      LinkedList();
      这个自定义的链表类,类似于C#中的链表,代码会在文章后面的贴出来。
自定义注册机类:
 function register(){//注册机类
      this.event=""; //事件执行代码
      this.eventList=new LinkedList();//用于储存事件的链表 属于注册机的属性
      this.addEvent=function(evnet){//将事件名加到事件链表中
          for(var itr = this.eventList.iterator();itr.hasNext(); )//如果id有重复的事件者不重复注册
         {
              var itm = itr.next();
              if(itm.id==evnet.id){
                  return "";
              }
         }
         this.eventList.add(evnet);
     }
     this.delEvent=function(id){//按照事件id注销事件
         var i=0;
         for(var itr = this.eventList.iterator();itr.hasNext(); )
         {
              var itm = itr.next();
              if(itm.id==id){
                  this.eventList.remove(i);//删除链表中的元素
                  return "";
               }
               i++;
          }
     }
     this.doEvent=function(){ //循环执行注册机内已经注册的事件
           for(var itr = this.eventList.iterator();itr.hasNext(); )
            {
                 var itm = itr.next();
                 eval(itm.value);//通过eval函数执行 函数字符串
            }
     }
}    
事件类:
 //事件对象
function event(){
       this.id="";//事件标记id
       this.value="alert(\"默认事件!\")"; //事件值也就是要执行的 代码或者是事件名称
}
      以上的代码还是很初级的,注释也些了,我就不具体解释了,有不懂的地方给我留言我会尽力解答,有什么写的不好的地方欢迎大家的板砖。下面是用于测试的界面也的也很简单,主要是一种事件行为控制的思想吧。前些时间在学习观察模式的时候也写了一个小例子出来,过几天贴出来。
测试页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>js注册机</title>
<script language="javascript" type="text/javascript">
//链表对象-----------------------------------------------------------------------------------------------------------------------
function Entry(next, data)
{
       this.next = next
       this.data = data
}

function Iterator(node)
{
       this.cousor = node
       this.hasNext = function ()
       {
               return (this.cousor.next != null);
       }
       this.next = function ()
       {
               var rt = this.cousor.next
               this.cousor = this.cousor.next
               return rt.data
       }
       this.replaceData=function(datar){
               this.cousor.data=datar
           
       }
}

function LinkedList()
{
       this.head = new Entry(null, null)
       this.size = function ()
       {
               var size = 0
               if (this.head == null)
               {
                       return size
               }

               var p = this.head.next
               for(; p!=null; p = p.next)
               size++;
               return size;
       }

       this.clear = function ()
       {
               this.head = null
       }

       this.getNode =  function (idx)
       {
               var pos = -1;
               var p = this.head
               while (p != null && pos < idx) {
                       p = p.next;
                       pos ++;
               }
               return p;
       }

       this.gett = function (idx)
       {
               return this.getNode(idx).data
       }

       this.add = function (data)
       {
               this.insert(this.size(), data)
       }
   
       this.insert = function (idx, data)
       {
               var p = this.getNode(idx-1); /*注意查询idx-1*/
               if (p == null){
                       return
               }
               var node = new Entry(p.next, data)
               p.next = node
       }

       this.remove = function (idx)
       {
               var prenode = this.getNode(idx - 1)
               var node = this.getNode(idx)
               if (prenode == null || node == null)
               {
                       return null
               }
               prenode.next = node.next
               return node.data
       }

       this.iterator = function ()
       {
               return new Iterator(this.head)
       }

       this.swap = function (a, b)
       {
               var av = this.getNode(a)
               var bv = this.getNode(b)
               var tmp = av.data
               av.data = bv.data
               bv.data = tmp
       }
       this.replace=function(index,data){
                    var j=0;
                     for(var itr =this.iterator(); itr.hasNext(); ){
                        itr.next();
                        if(index==j) itr.replaceData(data);
                        j++;
                    }
       }

}
//链表对象-----------------------------------------------------------------------------------------------------------------------
</script>
</head>
<input type="button" οnclick="registerMove()" value="注册移动事件" />
<input type="button" οnclick="registerStop()" value="注册停止事件" />
<input type="button" οnclick="registerClose()" value="注册关闭事件" />
<input type="button" οnclick="registerAll()" value="注册所有事件" />
<br/>
<br/>
请输入删除事件的ID:<input type="textbox" id="eventDelID" /> <input type="button" οnclick="registerDel()" value="删除事件" />
<br/>
<br/>
<input  type="button" οnclick="doEvent()"  value="触发器" />
<body>
<script language="javascript" type="text/javascript">
var oneregister=new register();
function register(){
 this.event=""; //事件执行代码
 this.eventList=new LinkedList();//用于储存事件的链表 属于注册机的属性
 this.addEvent=function(evnet){//将事件名加到事件链表中
   for(var itr = this.eventList.iterator();itr.hasNext(); )//如果id有重复的事件者不注册
         {
    var itm = itr.next();
    if(itm.id==evnet.id){
     return "";
    }
    }
   this.eventList.add(evnet);
 }
 this.delEvent=function(id){//将事件名加到事件链表中
  var i=0;
   for(var itr = this.eventList.iterator();itr.hasNext(); )//如果id有重复的事件者不注册
         {
    
    var itm = itr.next();
    if(itm.id==id){
      this.eventList.remove(i);
      return "";
    }
    i++;
    }
 }
 this.doEvent=function(){
   //循环执行注册机内的事件
    for(var itr = this.eventList.iterator();itr.hasNext(); )
            {
                 var itm = itr.next();
     eval(itm.value);
            }
 }
}

//事件对象
function event(){
 this.id="";
 this.value="alert(\"默认事件!\")";
}

function registerMove(){ 
 var  e=new event();
 e.id="move";
 e.value="alert(\"执行了移动事件!\")";
 oneregister.addEvent(e);
}
function registerStop(){ 
 var  e=new event();
 e.id="stop";
 e.value="alert(\"执行了停止事件!\")";
 oneregister.addEvent(e);
}
function registerClose(){ 
 var  e=new event();
 e.id="close";
 e.value="eventClose()";
 oneregister.addEvent(e);
}
function registerAll(){
 var  e=new event();
 e.id="move";
 e.value="alert(\"执行了移动事件!\")";
 oneregister.addEvent(e);
 var  e=new event();
 e.id="stop";
 e.value="alert(\"执行了停止事件!\")";
 oneregister.addEvent(e);
 var  e=new event();
 e.id="close";
 e.value="eventClose()";
 oneregister.addEvent(e);
}

function eventClose(){
  alert("执行了关闭事件");
}

//删除事件
function registerDel(){
 var id=document.getElementById('eventDelID').value;
 oneregister.delEvent(id);
}

//触发器
function doEvent(){
  oneregister.doEvent();
}
</script>
</body>
</html>

转载于:https://www.cnblogs.com/mylord/archive/2009/08/19/1550189.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值