シミュレーションはjQueryの$()を実現する.on()と$().trigger()


前言:$().on() $().trigger()を単純にシミュレートしただけで、idセレクタのみをサポートし、イベントバブルとイベント依頼をサポートします.
コード:



  
    jQuery          




A
B
// let events={} function $(elemId){ // const element=document.querySelector(elemId) // console.log(element,'element27') function returnTrue(){ return true } function returnFalse(){ return false } $.event={ // add:function (elemId,type,selectorReal,callbackReal) { let elemData=events[elemId] if(!elemData){ events[elemId]=elemData={} } elemData.handle=function(nativeEvent){ // this return $.event.dispatch.call(this,nativeEvent) } if(!elemData[type]){ elemData[type]=[] elemData[type].delegateCount=0 //addEventListener document.querySelector(elemId).addEventListener(type,elemData.handle) } let handlersCount=elemData[type].length let handlerObj={ type:type, handler:callbackReal, guid:++handlersCount, selector:selectorReal, } if ( selectorReal ) { // handlers.delegateCount++ elemData[type].splice( elemData[type].delegateCount++, 0, handlerObj); } else { elemData[type].push(handlerObj) } }, dispatch:function (nativeEvent,) { let event=$.event.fix(nativeEvent) let handlers=events['#'+this.id][event.type] // this let handlerQueue=$.event.handlers.call(this, event, handlers ) // , , let matched,handleObj let i=0 while((matched=handlerQueue[i++])&&!event.isPropagationStopped()){ let j=0 while((handleObj=matched.handlers[j++])){ event.handleObj=handleObj handleObj.handler(event) } } // return event }, fix:function (nativeEvent,) { let $event={} // MouseEvent $event.originalEvent=nativeEvent $event.target=nativeEvent.target $event.type=nativeEvent.type // delegateTarget: div#A, // currentTarget: div#A, $event.timeStamp=Date.now() $event.stopPropagation=function() { this.isPropagationStopped = returnTrue; nativeEvent.stopPropagation() } $event.isPropagationStopped=returnFalse //fix $event['chen'+(new Date()).valueOf()]=true return $event }, handlers:function (event,handlers) { let delegateCount = handlers.delegateCount let cur=event.target let handlerQueue=[] for(;cur!==this;cur=cur.parentNode||this){ let matchedHandlers = [] for(let i=0;i<delegateCount;i++){ let handleObj=handlers[i] matchedHandlers.push( handleObj ) handlerQueue.push( { elem: cur, handlers: matchedHandlers } ) } } cur=this if ( delegateCount < handlers.length ) { handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ) } return handlerQueue }, trigger:function (elemId,type) { let element=document.querySelector(elemId) let eventPath=[] let cur=element let event={} event.target=cur event.type=type for(;cur;cur=cur.parentNode){ eventPath.push( cur ); } let i=0 // while((cur=eventPath[i++])){ let handle=events['#'+cur.id]&&events['#'+cur.id].handle if(handle){ handle.call(cur,event) } } }, } return { on:function (type,selector,callback) { let callbackReal,selectorReal if(!type){ return } // selector funcion , if(typeof selector==='function'&&!callback){ selectorReal=undefined callbackReal=selector }else if(typeof selector==='string'&&callback){ selectorReal=selector callbackReal=callback } return $.event.add(elemId,type,selectorReal,callbackReal) }, trigger:function (type) { return $.event.trigger(elemId,type) }, } } // id , //=========test1=============== $("#A").on("click" ,function (event) { console.log(event,"A ") }) $("#A").on("click" ,function (event) { console.log(event,"A ") }) //=========test2=============== // $("#A").on("click" ,function (event) { // console.log(event,"A ") // }) // $("#A").on("click" ,"#B",function (event) { // event.stopPropagation() // console.log(event,"B A ") // }) //=========test3=============== // $("#A").on("click" ,function (event) { // console.log(event,"A ") // }) // $("#B").on("click",function (event) { // // event.stopPropagation() // console.log(event,"B ") // }) //==========test4============== // $("#A").on("click" ,function (event) { // console.log(event,"A ") // }) // $("#A").on("click" ,function (event) { // console.log(event,"A ") // }) // $("#A").trigger("click")

前編のフローチャートに基づいて書けばいいです.
考え方を見てください.
(完)