1 Jx().$package(function(J){ 2 var EventParser=J.Class({ 3 init: function() { 4 var _this= this; 5 this.op= [ 6 { 7 ".": function(word,target) { 8 return target.className==word; 9 }, 10 "+": function(word,target) { 11 return target.getAttribute(word); 12 }, 13 "#": function(word,target) { 14 return target.id==word; 15 }, 16 ".~": function(word,target) { 17 return $D.hasClass(target,word); 18 } 19 }, 20 { 21 ">": function(word,e) { 22 var p,wordP,wordS,s; 23 s= word.split(">"); 24 wordP= s[0]; 25 wordS= s[1]; 26 //通配符支持 27 if( (wordS=="*"?true:_this.match(wordS,e)) && 28 (p= _this.operate(_this.detectAncestor, wordP, e)())) {//检测符合特征的祖先节点 29 return _this.packEvent(e, p); 30 } 31 return false; 32 } 33 }, 34 { 35 "!": function(word,e) { 36 word= word.substr(1); 37 return !_this.match(word,e); 38 } 39 }, 40 { 41 "&&": function(word,e) { 42 var wordL,wordR,s; 43 s= word.split("&&"); 44 wordL= s[0]; 45 wordR= s.slice(1).join(""); 46 if(_this.match(wordL,e)) { 47 if(wordR.indexOf("&&")==-1) { 48 return _this.match(wordR,e); 49 }else { 50 return arguments.callee(wordR,e); 51 } 52 } 53 return false; 54 } 55 } 56 ]; 57 //优先级从下往上递减,对应于this.op 58 this.op2Level= [ 59 [".","#","+",".~"],//第一级操作符 60 ">",//第二级操作符 61 "!",//第三级操作符 62 "&&"//第四级操作符 63 ]; 64 }, 65 //寻找符合特征的祖先节点 66 detectAncestor: function(word, e, func) { 67 //if over 5...sorry. 68 //I think you should never touch the limit. 69 var max=5; 70 var target= e.target; 71 return function () { 72 if(func(word,target)) { 73 return target; 74 }else if(max>0) { 75 max--; 76 if(target.parentNode) { 77 target= target.parentNode; 78 }else { 79 max= 0; 80 } 81 return arguments.callee(); 82 } 83 return null; 84 } 85 }, 86 //用于对target跟特征的匹配 87 //因为e.target并不总是我们期待的target 88 detect: function(word, e, func) { 89 var target= e.target; 90 if(target.nodeType!=1) {//ipad下总是发生 91 target= target.parentNode; 92 if(func(word,target)) { 93 return this.packEvent(e,target); 94 } 95 }else { 96 return func(word,target); 97 } 98 return false; 99 }, 100 packEvent: function(e, target) { 101 return [true, 102 { 103 target: target, 104 oTarget: e.target, 105 stopPropagation: function(){ 106 e.stopPropagation(); 107 }, 108 preventDefault: function(){ 109 e.preventDefault(); 110 }, 111 pageX: e.pageX, 112 pageY: e.pageY 113 } 114 ]; 115 }, 116 operate: function(func,word,e) { 117 var p, 118 i=3;//("..#").length=3 由长至短检查是否有对应的第一级操作符 119 while(i>0) { 120 if(p= this.op[0][word.substr(0,i)]) { 121 var result= null; 122 if(result= func(word.substr(i),e,p)) { 123 return result; 124 } 125 } 126 i--; 127 } 128 return false; 129 }, 130 //按照层级进行匹配 131 match: function(word,e) { 132 var p; 133 //level > 0 134 for(var len=this.op2Level.length;len>0;len--) { //这里稍耗性能 135 var sig= this.op2Level[len]; 136 if(word.indexOf(sig) != -1 ) { 137 return this.op[len][sig](word,e,p); 138 } 139 } 140 //level 0 141 return this.operate(this.detect,word,e); 142 }, 143 //拆解并列条件(并列条件以","号分隔) 144 router: function(story/* .aa,.~bb,#cc,.aa>.dd */,e/* event */,p) { 145 var words= story.split(","); 146 var result; 147 for(p= words.length-1;p>=0;p--) { 148 if(result= this.match(words[p],e)) { 149 return result; 150 } 151 } 152 return false; 153 }, 154 //总入口 155 parse: function(story,func,e) { 156 var result= this.router(story,e); 157 if(result.length==2) { 158 func(result[1]); 159 }else if(result){ 160 func(e); 161 } 162 } 163 }); 164 J.event.eventParser= new EventParser(); 165 }); 166