高度な機能:javascriptカスタムイベントに役立ちます

32353 ワード

以前は「オリジナルjavascript jquery onメソッドのような動作リスニングを実現」という文章を書いていましたが、シーンを簡単に使うことができます.
ここでのカスタムイベントとはjavascriptのデフォルトのDOMとインタラクティブなイベントを区別することです.例えばclick、mouseover、changeなどです.ある動作が発生したかどうかを監視する必要がある場合があります.デフォルトの動作はシーンなど、十分ではありません.私たちはtab切替を書いて、クリックして非表示ラベルの内容をロードするように要求しました.
tab切替は非常に一般的な機能であり、通常はコンポーネントとして書かれ、要求をコンポーネントに書くたびにコンポーネントの拡張と結合性に影響を与えるに違いない.この場合、コンポーネント内でイベントブロードキャストをカスタマイズし、他の場所でこのブロードキャストを傍受してリクエストを実行すれば回避できます.
以上はシーンのみを使用していますが、以下は具体的な実装です.
1、簡易コード、基礎機能:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>     </title>
</head>
<body>
    <button id="demo">   </button>
    <script type="text/javascript">
        function Observer(){
            this._events={};
        }
        Observer.prototype={
            on:function(eName,fn,scope){
                eName=eName.toLowerCase();
                this._events[eName]=[];
                this._events[eName].push({fn:fn||null,scope:scope||null});
            },
            fireEvent:function(){
                var args=Array.prototype.slice.call(arguments);//       
                var eName=args.shift().toLowerCase();
                var list=this._events[eName];
                for(var i=0;i<list.length;i++){
                    var dict=list[i];
                    var fn=dict.fn;
                    var scope=dict.scope;
                    fn.apply(scope||null,args);//      
                }
            }
        }
        var listener=new Observer();
        listener.on("alert",function(name ,age){
            console.log(name+":"+age);
        });
        listener.on("aha",function(name ,age){
            console.log("        "+name+":"+age);
        });
        var $btn=document.getElementById("demo")
        $btn.onclick=function(){
            listener.fireEvent('aha', '     ', 28);
        }
    </script>
</body>
</html>

jqueryのonメソッドに似ています$(ele).on(type,fn).上のonは、現在のイベント名と関数を格納するオブジェクトであるイベントを登録します.FireEventは、イベントを解放、送信、傍受することとして理解される.
完全な実装:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>     </title>
</head>
<body>
    <button id="demo">   </button>
    <script type="text/javascript">
        function Observer() {
            this._events = {};
        }
        Observer.prototype = {
            constructor: this,
            addEvent: function(eName, fn) {
                if (typeof(eName) === "string" && typeof(fn) === "function") {
                    eName = eName.toLowerCase();
                    if (typeof(this._events[eName]) === "undefined") {
                        this._events[eName] = [fn];
                    } else {
                        this._events[eName].push(fn);
                    }
                }
                return this;
            },
            addEvents: function(obj) { //     
                obj = typeof(obj) === "object" ? obj : {};
                for (var eName in obj) {
                    if (eName && typeof(obj[eName] === "function")) {
                        this.addEvent(eName, obj[eName]);
                    }
                }
                return this;
            },
            fireEvent: function(eName) { //    
                if (eName && this._events[eName]) {
                    var events = {
                        eName: eName,
                        target: this
                    };

                    for (var length = this._events[eName].length, start = 0; start < length; start++) {
                        this._events[eName][start].call(this, events);
                    }
                }
                return this;
            },
            fireEvents: function(array) {
                if (array instanceof Array) {
                    for (var i = 0, len = array.length; i < len; i++) {
                        this.fireEvent(array[i]);
                    }
                }
                return this;
            },
            removeEvent: function(eName, key) { //       
                var eventsList = this._events[eName];
                if (eventsList instanceof Array) {
                    if (typeof(key) === "function") {
                        for (var i = 0, len = eventsList.length; i < len; i++) {
                            if (eventsList[i] === key) {//        
                                eventsList.splice(i, 1);
                                break;
                            }
                        }
                    } else if (key instanceof Array) {//            
                        for (var lis = 0, lenkey = key.length; lis < lenkey; lis += 1) {
                            this.removeEvent(type, key[lenkey]);
                        }
                    } else {//           
                        delete this._events[eName];
                    }
                }
                return this;
            },
            removeEvents: function(params) {
                if (params instanceof Array) {
                    for (var i = 0, length = params.length; i < length; i += 1) {
                        this.removeEvent(params[i]);
                    }
                } else if (typeof params === "object") {
                    for (var type in params) {
                        this.removeEvent(type, params[type]);
                    }
                }
                return this;
            }
        }
        var listeners = new Observer();
        listeners.addEvents({
            "once": function() {
                alert("         !");
                this.removeEvent("once");
            },
            "infinity": function() {
                alert("      ,     !");
            }
        });
        document.onclick = function(e) {
            e = e || window.event;
            var target = e.target || e.srcElement;
            if (!target || !/button/i.test(target.tagName)) {
                listeners.fireEvents(["once", "infinity"]);
            }
        };
    </script>
</body>
</html>

applyを変えて実現して、細心の注意を払ったあなたはその違いを発見しましたか?
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>     </title>
</head>
<body>
    <button id="demo">   </button>
    <script type="text/javascript">
        function Observer() {
            this._events = {};//      
        }
        Observer.prototype = {
            constructor: this,
            addEvent: function(eName, fn) {//    
                if (typeof(eName) === "string" && typeof(fn) === "function") {
                    eName = eName.toLowerCase();
                    if (typeof(this._events[eName]) === "undefined") {
                        this._events[eName] = [{//            
                            fn: fn
                        }];
                    } else {
                        this._events[eName].push({
                            fn: fn
                        });
                    }
                }
                return this;
            },
            addEvents: function(obj) { //     
                obj = typeof(obj) === "object" ? obj : {};
                for (var eName in obj) {
                    if (eName && typeof(obj[eName] === "function")) {
                        this.addEvent(eName, obj[eName]);
                    }
                }
                return this;
            },
            fireEvent: function(eName) {//    ,  !
                var args = Array.prototype.slice.call(arguments);//       
                var eName = args.shift().toLowerCase();//
                var list = this._events[eName];
                if(list instanceof Array){
                    for (var i = 0; i < list.length; i++) {
                    var dict = list[i];
                    var fn = dict.fn;
                    fn.apply(null, args);
                    }
                }
                return this;
            },
            fireEvents: function(array) {
                if (array instanceof Array) {
                    for (var i = 0, len = array.length; i < len; i++) {
                        this.fireEvent(array[i]);
                    }
                }
                return this;
            },
            removeEvent: function(eName, key) {
                var eventsList = this._events[eName];
                if (eventsList instanceof Array) {
                    if (typeof(key) === "function") {
                        for (var i = 0, len = eventsList.length; i < len; i++) {
                            if (eventsList[i] === key) {
                                eventsList.splice(i, 1);
                                break;
                            }
                        }
                    } else if (key instanceof Array) {
                        for (var lis = 0, lenkey = key.length; lis < lenkey; lis += 1) {
                            this.removeEvent(type, key[lenkey]);
                        }
                    }else{
                         delete this._events[eName];
                    }
                }
            }
        }
        var listeners = new Observer();
        listeners.addEvents({
            "once": function() {
                alert("         !");
                listeners.removeEvent("once");
            },
            "infinity": function() {
                alert("      ,       !");
            }
        });

        document.onclick = function(e) {
            e = e || window.event;
            var target = e.target || e.srcElement;
            if (!target || !/input|pre/i.test(target.tagName)) {
                listeners.fireEvents(["once", "infinity"]);
            }
        };
    </script>
</body>
</html>