<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="http://idcbgp.cn/static/lib/jquery/1.9.1/jquery.js" type="text/javascript"></script>
<title>模擬jQuery</title>
</head>
<body>
<p>模擬jQuery的整個(gè)事件流程綁定到執(zhí)行</p>
<p>包括</p>
<p>1. 通過on綁定</p>
<p>2. 通過dispatch派發(fā)</p>
<p>3. 通過fix修正事件對(duì)象</p>
<p>當(dāng)然這里還沒有涉及最重要的一點(diǎn)事件的委托過濾機(jī)制,考慮代碼太復(fù)雜了,后面會(huì)有分析</p>
<p id="aarontest" style="color:red">點(diǎn)擊執(zhí)行</p>
<script type="text/javascript">
//事件緩存
//用來代替jquery的data緩存
var eventCache = {};
var $$ = ajQuery = function(selector) {
return new ajQuery.fn.init(selector);
}
ajQuery.fn = ajQuery.prototype = {
name: 'aaron',
init: function(selector) {
this.selector = selector;
this[0] = document.querySelectorAll(selector)[0]
return this;
},
constructor: ajQuery
}
ajQuery.fn.init.prototype = ajQuery.fn
ajQuery.event = {
//增加事件
add:function(elem, types, handler){
var eventHandle = function(e) {
return ajQuery.event.dispatch.apply(elem, arguments)
};
//把用戶的回調(diào),放到緩存中
eventCache['handler'] = handler
if (elem.addEventListener) {
elem.addEventListener(types, eventHandle, false);
}
},
//派發(fā)事件
dispatch:function(event){
//修正事件對(duì)象
event = ajQuery.event.fix(event);
//var handlerQueue = ajQuery.event.handlers.call(this, event, eventCache['handler']);
eventCache['handler'].call(this,event)
},
//執(zhí)行事件句柄
handlers: function(event, handlers) {
var handlerQueue = [];
handlerQueue.push({
elem: this,
handlers: handlers.slice(delegateCount)
});
},
//修正事件對(duì)象
fix:function(event){
//原始事件引用
var originalEvent = event;
//鼠標(biāo)事件對(duì)象的屬性
var props= "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" ");
//創(chuàng)建事件對(duì)象
var event = new ajQuery.Event(originalEvent);
//混入事件屬性
i = props.length;
while (i--) {
prop = props[i];
event[prop] = originalEvent[prop];
}
return event
}
}
function returnTrue() {
return true;
}
function returnFalse() {
return false;
}
//模擬出事件對(duì)象
//增加調(diào)用判斷方法
ajQuery.Event = function(src, props) {
if (src && src.type) {
this.originalEvent = src;
this.type = src.type;
this.isDefaultPrevented = src.defaultPrevented ||
src.defaultPrevented === undefined &&
src.returnValue === false ?
returnTrue :
returnFalse;
} else {
this.type = src;
}
this.timeStamp = src && src.timeStamp || jQuery.now();
this[jQuery.expando] = true;
};
ajQuery.Event.prototype = {
isDefaultPrevented: returnFalse,
isPropagationStopped: returnFalse,
isImmediatePropagationStopped: returnFalse,
preventDefault: function() {
var e = this.originalEvent;
this.isDefaultPrevented = returnTrue;
if (e && e.preventDefault) {
e.preventDefault();
}
},
stopPropagation: function() {
var e = this.originalEvent;
this.isPropagationStopped = returnTrue;
if (e && e.stopPropagation) {
e.stopPropagation();
}
},
stopImmediatePropagation: function() {
var e = this.originalEvent;
this.isImmediatePropagationStopped = returnTrue;
if (e && e.stopImmediatePropagation) {
e.stopImmediatePropagation();
}
this.stopPropagation();
}
};
ajQuery.fn.on = function(types, fn) {
//參數(shù)過濾
//...............
ajQuery.event.add(this[0], types, fn);
}
$$('#aarontest').on('click',function(){
alert('通過click綁定,慕課網(wǎng)')
})
</script>
</body>
</html>