[转帖]Mootools源码分析-11 -- Event
原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-402067
/*
对原生event的包装
首先将其Native化
*/
var Event = new Native({
//族名,为$type提供精准类型判断
name: 'Event',
initialize: function(event, win) {
win = win || window;
var doc = win.document;
event = event || win.event;
//根据私有属性判断是否已包装
if (event.$extended) return event;
this.$extended = true;
var type = event.type;
//针对不同浏览器获取的事件源对象
var target = event.target || event.srcElement;
//nodeType为3时为空白节点,显然不是我们需要的,所以向上获取
while (target && target.nodeType == 3) target = target.parentNode;
if (type.test(/key/)) {
//针对不同浏览器获取的键值
var code = event.which || event.keyCode;
var key = Event.Keys.keyOf(code);
if (type == 'keydown') {
//经测试,这段兼容处理貌似还存在bug,希望后续版本会修正
var fKey = code - 111;
if (fKey > 0 && fKey < 13) key = 'f' + fKey;
}
key = key || String.fromCharCode(code).toLowerCase();
} else if (type.match(/(click|mouse|menu)/i)) {
//根据DTD的不同模式使doc指向不同节点
doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
var page = {
x: event.pageX || event.clientX + doc.scrollLeft,
y: event.pageY || event.clientY + doc.scrollTop
};
var client = {
x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX,
y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY
};
//滚轮支持
if (type.match(/DOMMouseScroll|mousewheel/)) {
var wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
}
//右键判断
var rightClick = (event.which == 3) || (event.button == 2);
//事件相关对象
var related = null;
if (type.match(/over|out/)) {
switch (type) {
case 'mouseover': related = event.relatedTarget || event.fromElement; break;
case 'mouseout': related = event.relatedTarget || event.toElement;
}
if (!(function() {
while (related && related.nodeType == 3) related = related.parentNode;
return true;
}).create({attempt: Browser.Engine.gecko})()) related = false;
}
}
return $extend(this, {
event: event,
type: type,
page: page,
client: client,
rightClick: rightClick,
wheel: wheel,
relatedTarget: related,
target: target,
code: code,
key: key,
shift: event.shiftKey,
control: event.ctrlKey,
alt: event.altKey,
meta: event.metaKey
});
}
});
//键盘代码的可读表示
Event.Keys = new Hash({
'enter': 13,
'up': 38,
'down': 40,
'left': 37,
'right': 39,
'esc': 27,
'space': 32,
'backspace': 8,
'tab': 9,
'delete': 46
});
//对Event的扩展实现
Event.implement({
//阻止事件冒泡和事件返回
stop: function() {
return this.stopPropagation().preventDefault();
},
//阻止事件冒泡
stopPropagation: function() {
if (this.event.stopPropagation) this.event.stopPropagation();
else this.event.cancelBubble = true;
return this;
},
//阻止事件返回
preventDefault: function() {
if (this.event.preventDefault) this.event.preventDefault();
else this.event.returnValue = false;
return this;
}
});
对原生event的包装
首先将其Native化
*/
var Event = new Native({
//族名,为$type提供精准类型判断
name: 'Event',
initialize: function(event, win) {
win = win || window;
var doc = win.document;
event = event || win.event;
//根据私有属性判断是否已包装
if (event.$extended) return event;
this.$extended = true;
var type = event.type;
//针对不同浏览器获取的事件源对象
var target = event.target || event.srcElement;
//nodeType为3时为空白节点,显然不是我们需要的,所以向上获取
while (target && target.nodeType == 3) target = target.parentNode;
if (type.test(/key/)) {
//针对不同浏览器获取的键值
var code = event.which || event.keyCode;
var key = Event.Keys.keyOf(code);
if (type == 'keydown') {
//经测试,这段兼容处理貌似还存在bug,希望后续版本会修正
var fKey = code - 111;
if (fKey > 0 && fKey < 13) key = 'f' + fKey;
}
key = key || String.fromCharCode(code).toLowerCase();
} else if (type.match(/(click|mouse|menu)/i)) {
//根据DTD的不同模式使doc指向不同节点
doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
var page = {
x: event.pageX || event.clientX + doc.scrollLeft,
y: event.pageY || event.clientY + doc.scrollTop
};
var client = {
x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX,
y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY
};
//滚轮支持
if (type.match(/DOMMouseScroll|mousewheel/)) {
var wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
}
//右键判断
var rightClick = (event.which == 3) || (event.button == 2);
//事件相关对象
var related = null;
if (type.match(/over|out/)) {
switch (type) {
case 'mouseover': related = event.relatedTarget || event.fromElement; break;
case 'mouseout': related = event.relatedTarget || event.toElement;
}
if (!(function() {
while (related && related.nodeType == 3) related = related.parentNode;
return true;
}).create({attempt: Browser.Engine.gecko})()) related = false;
}
}
return $extend(this, {
event: event,
type: type,
page: page,
client: client,
rightClick: rightClick,
wheel: wheel,
relatedTarget: related,
target: target,
code: code,
key: key,
shift: event.shiftKey,
control: event.ctrlKey,
alt: event.altKey,
meta: event.metaKey
});
}
});
//键盘代码的可读表示
Event.Keys = new Hash({
'enter': 13,
'up': 38,
'down': 40,
'left': 37,
'right': 39,
'esc': 27,
'space': 32,
'backspace': 8,
'tab': 9,
'delete': 46
});
//对Event的扩展实现
Event.implement({
//阻止事件冒泡和事件返回
stop: function() {
return this.stopPropagation().preventDefault();
},
//阻止事件冒泡
stopPropagation: function() {
if (this.event.stopPropagation) this.event.stopPropagation();
else this.event.cancelBubble = true;
return this;
},
//阻止事件返回
preventDefault: function() {
if (this.event.preventDefault) this.event.preventDefault();
else this.event.returnValue = false;
return this;
}
});
原作者:我佛山人