js自定义事件(监听,触发,删除)

事件类

/**
 * 自定义事件,用于事件的添加,监听,分发
 */
export default class  CustomEvents {
    static typeEvent = []
    static events = []
    static add(type,listener){
        const ce = new CustomEvent(type,{detail:{data:{}}})

        // 生成id
        let s = [];
        let hexDigits = "0123456789abcdef";
        for (let i = 0; i < 36; i++)
        {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
        s[8] = s[13] = s[18] = s[23] = "-";
        let id = s.join("");

        //存储事件
        const typeEvent ={type,event:ce}
        const event = {id,type,event:ce,listener}
        const isHasTypeEvt = CustomEvents.typeEvent.find(v=>v.type == type)
        if(!isHasTypeEvt) CustomEvents.typeEvent.push(typeEvent)
        document.addEventListener(type, listener)
        CustomEvents.events.push(event)
        return id
    }

  
    /**
     * 描述
     * @date 2021-05-25
     * @param {string} type 自定义事件类型名 
     * @param {string} listenerId 事件监听处理函数的句柄 id,由添加事件 on 函数返回
     * @returns {boolean} 
     */
    static remove(type,listenerId){
        var index =-1
        for(let i=0;i<CustomEvents.events.length;i++){
            if(CustomEvents.events[i].type==type&&CustomEvents.events[i].id==listenerId){
                index = i
                break
            }
        }

        if(index!=-1){
            document.removeEventListener(type, CustomEvents.events[index].listener)
            CustomEvents.events.splice(index,1)
            // 没有对应类型事件,清除类型事件记录
            const typeEvent = CustomEvents.events.find(v=>v.type == type)
            if(!typeEvent){
                const index = CustomEvents.typeEvent.findIndex(v=>v.type == type)
                if(index!=-1){
                    CustomEvents.typeEvent.splice(index,1)
                }
            }
            return true
        }else{
            return false
        }  
    }
 	/**
     * 触发事件
     * @param {CustomEventType/number} type  事件类型
     * @param {object} data 事件携带的数据
     */
    static dispatch(type,data){
        const typeEvt = CustomEvents.typeEvent.find(v=>v.type ==type)
        if(typeEvt){
            typeEvt.event.detail.data = data
            document.dispatchEvent(typeEvt.event)
        }
    }
}

简单的事件设计类,包含的功能有,事件定义,监听,触发,删除

事件类型 枚举类

/**
 * 自定义事件类型
 */
class CustomEventType  {
    static Event1=1 // 请求报价事件
    static Event2=0 // 所有任务完成事件
}


export default CustomEventType

用于事件枚举值,当然也可以直接以静态属性定义在 CustomEvents 类中,类似这样

/**
 * 自定义事件,用于事件的添加,监听,分发
 */
export default class  CustomEvents {
    static type ={
      Event1 =1,
      Event2 =0
    }
}

使用

1.监听

CustomEvents.add( CustomEventType.Event1,DealFuncXX)

2.触发

CustomEvents.dispatch(CustomEventType.Event1,{你的data对象})

3.移除

CustomEvents.remove(CustomEventType.Event1)

运行示例:等我补哈 🙂

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>事件DEMO</title>
    <!-- Load React. -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
    <script>
        /**
         * 自定义事件,用于事件的添加,监听,分发
         */
        class CustomEvents {
            static typeEvent = []
            static events = []
            static add(type, listener) {
                const ce = new CustomEvent(type, {
                    detail: {
                        data: {}
                    }
                })

                // 生成id
                let s = [];
                let hexDigits = "0123456789abcdef";
                for (let i = 0; i < 36; i++) {
                    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
                }
                s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
                s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
                s[8] = s[13] = s[18] = s[23] = "-";
                let id = s.join("");

                //存储事件
                const typeEvent = {
                    type,
                    event: ce
                }
                const event = {
                    id,
                    type,
                    event: ce,
                    listener
                }
                const isHasTypeEvt = CustomEvents.typeEvent.find(v => v.type == type)
                if (!isHasTypeEvt) CustomEvents.typeEvent.push(typeEvent)
                document.addEventListener(type, listener)
                CustomEvents.events.push(event)
                return id
            }


            /**
             * 描述
             * @date 2021-05-25
             * @param {string} type 自定义事件类型名 
             * @param {string} listenerId 事件监听处理函数的句柄 id,由添加事件 on 函数返回
             * @returns {boolean} 
             */
            static remove(type, listenerId) {
                var index = -1
                for (let i = 0; i < CustomEvents.events.length; i++) {
                    if (CustomEvents.events[i].type == type && CustomEvents.events[i].id == listenerId) {
                        index = i
                        break
                    }
                }

                if (index != -1) {
                    document.removeEventListener(type, CustomEvents.events[index].listener)
                    CustomEvents.events.splice(index, 1)
                    // 没有对应类型事件,清除类型事件记录
                    const typeEvent = CustomEvents.events.find(v => v.type == type)
                    if (!typeEvent) {
                        const index = CustomEvents.typeEvent.findIndex(v => v.type == type)
                        if (index != -1) {
                            CustomEvents.typeEvent.splice(index, 1)
                        }
                    }
                    return true
                } else {
                    return false
                }
            }
            /**
             * 触发事件
             * @param {CustomEventType/number} type  事件类型
             * @param {object} data 事件携带的数据
             */
            static dispatch(type, data) {
                const typeEvt = CustomEvents.typeEvent.find(v => v.type == type)
                if (typeEvt) {
                    typeEvt.event.detail.data = data
                    document.dispatchEvent(typeEvt.event)
                }
            }
        }

        window.CustomEvents = CustomEvents
    </script>

</head>

<body>
    <div id="container">:)</div>
    <!-- Load our React component. -->
    <script type="text/babel">
        function EventList(props){
            const items = props.events&&props.events.map((event)=>{
                 return <li key={event.id}>type: {event.type}  id: {event.id}   <button value={event.id}>移除</button>  <button value={event.id}>触发</button> </li> 
            })

            return (
                <div>事件<br/>
                    <ul>{items}</ul>
                </div>
                
            )

        }


        class MainContain extends React.Component{
            // this 指向Component内部
            constructor(props){
                super(props)
                this.state = {
                    events:CustomEvents.events
                    
                }
            }
            reload(){
                location.reload()
            }

            onclick(e){
                switch (e.target.value) {
                    case 'add':
                    CustomEvents.add("a",()=>{})
                    this.setState(()=>({
                        events:CustomEvents.events
                    }))
                        break;
                    case 'remove':

                        break;
                    case 'emit':
                        
                        break;
                
                    default:
                        break;
                }
            }

            render(){
                return (
                    <div>
                        <h1>事件DEMO</h1>
                        <div>事件数:{this.state.events.length}
                        
                        </div>
                        <div><button value='add' onClick={this.onclick.bind(this)}>添加</button> <input type='text' placeholder='事件类型名,例如 a'/></div>
                        <div><button value='remove' onClick={this.onclick.bind(this)}>移除</button></div>
                        <div><button value='emit'  onClick={this.onclick.bind(this)}>触发</button></div>
                        <div><button onClick ={this.reload}>重置</button></div>
                        <br />
                        <EventList events={this.state.events}></EventList>
                        
                    </div>
                )
            }


        }



        const domContainer = document.querySelector('#container');
        ReactDOM.render(<MainContain ></MainContain>, domContainer); 
    </script>

</body>

</html>
事件DEMO
🙂