js自定义事件

Posted vcxiaohan2

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js自定义事件相关的知识,希望对你有一定的参考价值。

自定义事件(简单版)

let Event = 
    /*
    绑定事件
    Event.on('log', function(param1, param2) // 绑定一个log事件,并接收param1和param2参数
        console.log(1, param1, param2)
    )
    */
    on(event, cb) 
        if (!this.handles) 
            this.handles = 
        
        if (!this.handles[event]) 
            this.handles[event] = []
        
        this.handles[event].push(cb)
    ,
    /*
    触发事件
    Event.emit('log', 'param1', 'param2')// 触发所有log事件,并传送param1和param2参数
    */
    emit(event) 
        if (this.handles[arguments[0]]) 
            for (let i = 0; i < this.handles[arguments[0]].length; i++) 
                this.handles[arguments[0]][i](...[].slice.call(arguments, 1))
            
        
    ,
    /*
    移除事件
    Event.off('log')// 移除所有log事件
    */
    off(event) 
        if (this.handles[event]) 
            delete this.handles[event]
        
    


// 绑定log事件,并接收param1和param2参数
Event.on('log', function (param1, param2) 
    console.log('log', param1, param2)
)
// 触发log事件,并传送1和2参数
Event.emit('log', 1, 2)// log 1 2
// 移除log事件
Event.off('log')
// 触发log事件(由于以上已移除,所以不能触发)
Event.emit('log')

自定义事件(复杂版)

 let Event = 
     /*
     绑定事件
     Event.on('log', function(param1, param2) // 绑定一个log事件,并接收param1和param2参数,仅在移除log的所有事件时才能清除该绑定事件
         console.log(1, param1, param2)
     )
     Event.on('log.a log.b', function() // 绑定2个事件,一个是标记为a的log事件,一个是标记为b的log事件
         console.log(2)
     )
     */
     on(/* event, callback */) 
         let event = arguments[0].split(' ')
         for (let i = 0; i < event.length; i++) 
             let _event = event[i].match(/([^\\.]+)\\.*([^\\.]*)/),
                 eventType = _event[1],
                 eventMark = _event[2]
             if (!this.handles) 
                 this.handles = 
             
             if (!this.handles[eventType]) 
                 this.handles[eventType] = 
             
             if (!this.handles[eventType][eventMark]) 
                 this.handles[eventType][eventMark] = []
             
             this.handles[eventType][eventMark].push(arguments[1])
         
     ,
     /*
     触发事件
     Event.emit('log', 'param1', 'param2')// 触发所有log事件,并传送param1和param2参数
     Event.emit('log.a')// 触发标记为a的log事件
     */
     emit(/* event, params1, params2... */) 
         let _event = arguments[0].match(/([^\\.]+)\\.*([^\\.]*)/),
             eventType = _event[1],
             eventMark = _event[2]
         if (this.handles) 
             let eventTypeObj = this.handles[eventType]
             if (eventTypeObj) 
                 if (eventMark) 
                     _cb(eventMark, eventTypeObj, arguments)
                  else 
                     for (let eventMark in eventTypeObj) 
                         _cb(eventMark, eventTypeObj, arguments)
                     
                 
             
         
         function _cb(eventMark, eventTypeObj, _arguments) 
             if (eventTypeObj[eventMark]) 
                 for (let i = 0; i < eventTypeObj[eventMark].length; i++) 
                     eventTypeObj[eventMark][i](...[].slice.call(_arguments, 1))
                 
             
         
     ,
     /*
     移除事件
     Event.off('log')// 移除所有log事件
     Event.off('log.a')// 仅移除绑定的标记是a的log事件
     */
     off(/* event */) 
         let _event = arguments[0].match(/([^\\.]+)\\.*([^\\.]*)/),
             eventType = _event[1],
             eventMark = _event[2]
         if (eventMark) 
             delete this.handles[eventType][eventMark]
          else 
             delete this.handles[eventType]
         
     
 

 // 绑定log事件,并接收param1和param2参数
 Event.on('log', function (param1, param2) 
     console.log('log', param1, param2)
 )
 // 绑定标记为a和b的事件
 Event.on('log.a log.b', function () 
     console.log('log.a/b')
 )
 // 绑定标记为a事件
 Event.on('log.c', function () 
     console.log('log.c')
 )
 // 触发所有log事件,并传送1和2参数
 Event.emit('log', 1, 2)// log 1 2 log.a/b log.a/b log.c
 // 移除标记为a的事件
 Event.off('log.a')
 // 触发标记为a的事件(由于以上已移除,所以不能触发)
 Event.emit('log.a')
 // 触发标记为c的事件
 Event.emit('log.c')// log.c

扩展(原生js实现jquery的on和off事件)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>demo</title>
    <style>
        * 
            margin: 0;
            padding: 0;
        

        body,
        html 
            width: 100%;
            height: 100%;
        
    </style>
</head>

<body>
    <button class="a">a 按下</button>
    <button class="b">b 按下</button>
    <button class="c">c 按下</button>
</body>
<script>
    let Event = 
        /*
        绑定事件 (>=ie9)
        Event.on(el, 'mousedown', function() // 给el绑定一个随机标记的mousedown事件,仅在移除el所有事件时才能清除该绑定事件
        console.log(1)
        )
        Event.on(el1, el2, ..., 'mousedown.a mouseup.b', function() // 给所有的元素都绑定2个事件,一个是标记为a的mousedown事件,一个是标记为b的mouseup事件
        console.log(2)
        )
        */
        on(/*el, event, callback*/) 
            var el = [],
                event = [],
                callback = null;

            for (var i = 0; i < arguments.length; i++) 
                switch (this.isType(arguments[i])) 
                    case 'window':
                    case 'html':
                        el.push(arguments[i]);
                        break;
                    case 'string':
                        event = arguments[i].split(' ');
                        break;
                    case 'function':
                        callback = arguments[i];
                        break;
                
            

            for (var i = 0; i < el.length; i++) 
                for (var j = 0; j < event.length; j++) 
                    var _event = event[j].match(/([^\\.]+)\\.*([^\\.]*)/),
                        eventType = _event[1],
                        eventMark = _event[2];

                    if (!eventMark) 
                        eventMark = ('' + Math.random()).replace('.', '');
                    
                    if (!this.event) 
                        this.event = ;
                    
                    this.event[eventMark] = callback;

                    el[i].addEventListener(eventType, this.event[eventMark]);
                
            
        ,
        /*
        移除事件 (>=ie9)
        Event.off(el, 'mousedown')// 移除el绑定的所有mousedown事件
        Event.off(el, 'mousedown.a')// 仅移除el绑定的标记是a的mousedown事件
        Event.off(el1, el2, ..., 'mousedown.b')// 移除所有元素绑定的标记是b的mousedown事件
        */
        off(/*el, event*/) 
            var el = [],
                event = [];

            for (var i = 0; i < arguments.length; i++) 
                switch (this.isType(arguments[i])) 
                    case 'window':
                    case 'html':
                        el.push(arguments[i]);
                        break;
                    case 'string':
                        event = arguments[i].split(' ');
                        break;
                
            

            for (var i = 0; i < el.length; i++) 
                for (var j = 0; j < event.length; j++) 
                    var _event = event[j].match(/([^\\.]+)\\.*([^\\.]*)/),
                        eventType = _event[1],
                        eventMark = _event[2];

                    el[i].removeEventListener(eventType, this.event[eventMark]);
                    if (!eventMark) 
                        for (var key in this.event) 
                            el[i].removeEventListener(eventType, this.event[key]);
                        
                    
                
            
        ,
        /*
        判断类型 array number string date function regexp object boolean null undefined html
        Event.isType(document.querySelector('p'), 'html')// true
        */
        isType(obj, type) 
            var _type = Object.prototype.toString.call(obj).toLowerCase();

            if (_type.indexOf('html') + 1) 
                _type = 'html';
             else 
                _type = _type.replace('[object ', '').replace(']', '');
            

            return type ? _type == type : _type;
        
    

    // 给a绑定mousedown事件
    Event.on(document.querySelector('.a'), 'mousedown', function () 
        console.log(1)
    )
    // 给b和c都绑定2个事件,一个是标记为a的mousedown事件,一个是标记为b的mouseup事件
    Event.on(document.querySelector('.b'), document.querySelector('.c'), 'mousedown.a mouseup.b', function () 
        console.log(2)
    )
    // 给c移除一个是标记为a的mousedown事件
    Event.off(document.querySelector('.c'), 'mousedown.a')
</script>

</html>

谈谈JS的观察者模式(自定义事件)

以上是关于js自定义事件的主要内容,如果未能解决你的问题,请参考以下文章

js自定义事件DOM/伪DOM自定义事件

js-自定义事件

js事件模型与自定义事件

js自定义事件模式

Node.js自定义对象事件监听与发射

自定义事件 js