高级功能:很有用的javascript自定义事件

之前写了篇文章《原生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>
时间: 2024-10-11 22:10:58

高级功能:很有用的javascript自定义事件的相关文章

19个很有用的 JavaScript库推荐

流行的 JavaScript 库有jQuery,MooTools,Prototype,Dojo和YUI等,这些 JavaScript 库功能丰富,加上它们众多的插件,几乎能实现任何你需要的功能 然而需要实现一些特定的功能,则可以选择功能更专一的轻量库,今天这篇文章与大家分享16个很有用的 JavaScript 库. Blackbird: Open Source JavaScript Logging UtilityBlackbird 是一款非常酷的 JavaScript 调试工具,带有一个漂亮的界

【转载】100多个很有用的JavaScript函数以及基础写法大集合

1.document.write("");为 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4.一个浏览器窗口中的DOM顺序是:window->(navigator,screen,history,location,document) 5.得到表单中元素的名称和值:document.getElementById("表单中元素的ID号").name(或value) 6.一个小写转

JavaScript 自定义事件

Javascript事件模型系列(四)我所理解的javascript自定义事件 漫谈js自定义事件.DOM/伪DOM自定义事件

JavaScript自定义事件,动态添加属性

根据事件的不同,可用的自定义方法也不同. document.createEvent('Event'); 实现主要有4个步骤: 1.创建事件. 2.初始化事件(三个参数:事件名,是否起泡,是否取消默认触发) 3.监听事件 4.触发事件 var Evt = document.createEvent('Event');//创建一个事件 Evt.initEvent('inputChangeEvt', true, true);//初始化事件,给定事件名字 window.addEventListener('

Javascript 自定义事件 (custom event)

Javascript 中经常会用到自定义事件.如何创建一个简单的自定义事件呢?在创建自定义的事件之前,我们应该考虑一下和事件有关的东西.例如 click 事件,首先我们要能注册一个click事件(在一个button上绑定click事件),然后要能够触发这个事件,最后事件不需要的时候要能够移除事件. 我们可以借助JQuery 的方法来实现自定义事件,请看下面的例子: <div id="myDiv">myDiv</div> <script type="

JavaScript 自定义事件而不用 MVC 者,都是耍流氓

自定义事件这事儿,得用 MVC. 宝宝和我说,凡是写事件不用 MVC 者,都是耍流氓.我对此深以为然. 其实宝宝只说过后半句. 事件这玩意儿,从实现上来说,需要实现委托注册管理和事件触发回调这两块:从定义上来说,需要由事件服务定义委托管理和事件触发,由事件监听者定义委托注册和事件回调:从角色划分来说,需要分为服务者.触发者.监听者.这套排列组合,你已经乱了是吧.所以说,事件长得是这德性的: // 服务者 public delegate void EventHandler(object sende

JavaScript自定义事件 - createEvent()、initEvent()和dispachEvent()

参考资料: MDN - Document.createEvent():https://developer.mozilla.org/zh-CN/docs/Web/API/Document/createEvent MDN - Event.initEvent():https://developer.mozilla.org/zh-CN/docs/Web/API/Event/initEvent MDN - 创建和触发events:https://developer.mozilla.org/zh-CN/do

JavaScript自定义事件监听

一.事件的属性和方法 1 //事件Event 2 //属性:` 3 `bubbles`:布尔值,是否会冒泡 4 `cancelable`:布尔值,是否可以取消默认动作 5 `target`:目标对象 6 `currentTarget`:当前对象 7 `timeStamp`:时间戳(相对于某个时刻) 8 `type`:事件类型,即注册该事件的名字 9 `eventPhase`:返回事件传播的当前阶段 10 11 12 //方法 13 1.event.stopPropagation(); 阻止冒泡

Javascript自定义事件

触发用户自定义事件,已成为各前端框架的基本技术.(较新版本的浏览器才支持) 页面 <div id="outer"> <div id="inner">Leonardo Da Vinci</div> </div> <button onclick="tiggerMyEvent();">触发事件</button> 脚本 document.querySelector("#ou