Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

イベント状態管理

LDRインスパイヤされたのでやってみたいなあと思ってたんだけど。
新しくevent周りを書き直してみた。

一部抜粋

Kumu.extend(Kumu.Event, {
  
  PID : 0, 
  
  process : {},  
  
  nodeCache : {},
  
  elementsById : function(id){
    if(!(id instanceof String) && typeof id != "string"){
      return [id];
    }

    var nodes = [];
    var elem = $i(id);
    if(!this.nodeCache[id]){
      this.nodeCache[id] = []; 
    }
    while(elem){
      if(!elem["cached"]){
        nodes.push(elem);
      }
      elem.id = "";
      elem = $i(id);
    }
    this.nodeCache[id] = this.nodeCache[id].concat(nodes);
    this.nodeCache[id].map(function(n){
      n.id = id;
      n.cached = true;
    } );
    return this.nodeCache[id];
  },
  
  stopEvent : function(event) {
    if (event.preventDefault) { 
      event.preventDefault(); 
      event.stopPropagation(); 
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  },
  
  unloadEvent: function() {
    if (!this.process){
      return;
    }
    var p = this.process;
    for (var v in this.p){
    	p[v].remove();
    }
    this.p = {};
  },

  addEvent : function(element, name, observer, useCapture) {
    var nodes = this.elementsById(element);
    useCapture = useCapture || false;
    if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) 
     || ele.attachevent)){
      name = 'keydown';
    }
    nodes.map(function(node){
      this.PID = this.PID +1;
      var nodeFunc = observer.state();
      var p = {
        node : node,
        eventName : name,
        command : nodeFunc,
        add : function(){
          if (node.addEventListener) {
            node.addEventListener(name, nodeFunc, useCapture);
          } else if (node.attachEvent) {
            node.attachEvent('on' + name, nodeFunc);
          }
        },
        remove : function(){
          if (node.removeEventListener) {
  	        node.removeEventListener(name, nodeFunc, useCapture);
    	  } else if (node.detachEvent) {
            node.detachEvent('on' + name, nodeFunc);
          }
        },
        cancel : function(c){
        	nodeFunc.cancel(c);
		}
      };
      this.process[this.PID] = p;
      p.add();
    }.bindScope(this));
  },
 
  regist : function(o){
    for(var v in o){
      o[v].__name = v;
      o[v].registEvent();
    }
  },
    
  loadEvent : function(){
    if(KumuEventConf){
      this.regist(KumuEventConf);
    }
  },
  
  addOnLoadEvent : function(func){
    this.addEvent(window, 'load', func, false);
  }
  
});

PIDに全てを紐付けてます。
一度removeしてもaddで再度割り付けたりできます。
状態も付けてみた。

サンプル

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<script language="JavaScript" type="text/javascript" src="../js/kumu/kumu.js"></script>
<script language="JavaScript" type="text/javascript" src="../js/kumu/event.js"></script>
<script language="JavaScript" type="text/javascript" src="../js/kumu/sample.js"></script>
<script>
function on(evt){
    var elem = (evt.target) ? evt.target : evt.srcElement;
    if(elem.nodeType == 3){
      elem = elem.parentNode;
    }
    elem.className = 'on';  
}

function off(evt){
    var elem = (evt.target) ? evt.target : evt.srcElement;
    if(elem.nodeType == 3){
      elem = elem.parentNode;
    }
    elem.className = 'off';  
}

KumuEventConf = {
  'click_test:id1' : o.debug.bindScope(o),
  'mouseover_test' : on,
  'mouseout_test' : off
}

function inspect(){
	for(var i in Kumu.Event.process){
	  var str = "PID:"+i+"::"+Kumu.Event.process[i].node+"::"+Kumu.Event.process[i].eventName+"::"+Kumu.Event.process[i].command.__state;
      var br = document.createElement("br");
      var span = document.createElement("span");
      document.body.appendChild(br);
      document.body.appendChild(span.appendChild(document.createTextNode(str)));
	}
}
</script>
<style type="text/css">
.on {
  background-color: #ffb;
}
.off{
  background-color: #f5f5f5;
}

</style>

</head>

<body>
<div id='test:id1'>アラートが出ます</div>
<div id='test'>TEST</div>
<div id='test'>TEST</div>
<div id='test'>TEST</div>
<div id='test'>TEST</div>
<input type="button" value="イベント一覧" onclick="inspect()">
</body>
</html>

イメージはこんなんです。

追記
PIDではわかりにくすぎなので普通に[node][event]で管理することにしました。
([node][event]で返ってくるのは配列)
stateを呼ぶかどうかは微妙ー。
うくく。