Jquery揭祕系列:談談bind,one,live,delegate事件及實現

 

      在Jquery裏面,咱們用的最多的就是事件綁定了,事件綁定有多個函數。例如:bind,one,live,delegate等等。java

      咱們先看看他們的定義,直接進入主題:dom

bind( )方法用於將一個處理程序附加到每一個匹配元素的事件上並返回jQuery對象。函數

.bind(eventType[, evnetData], Handler(eventObject))post

其中,參數eventType是一個字符串,包含一個或多個javaScript事件類 型,例如click,submit或自定義事件的名稱,指定多個事件類型時用空格分隔各個類型;eventData爲Map類型,給出要傳遞給事件處理程 序的數據,handler指定觸發該事件時要執行的函數,eventObject表示事件對象。性能

.bind()方法將事件處理程序handler附加到匹配元素集合中的每一個元素的eventType事件上,若是須要,還能夠向事件處理程序傳遞數據。this

live( )方法將一個事件處理程序附加到與當前選擇器匹配的全部元素(包含現有的或未來添加的)的指定事件上並返回jQuery對象。spa

.live(eventType,[eventData],handler)prototype

其中,參數eventType是一個字符串,包含一個或多個javaScript事件類 型,例如click,keydown或自定義事件的名稱,eventData是可選參數,爲Map類型,給出要傳遞給事件處理程序的數據,該參數是在 jQuery1.4中添加的;handler是一個函數,當觸發該事件時將執行這些函數code

.live()方法將事件處理程序handler附加到每一個匹配元素(包含當前存在的和未來添加的)的eventType事件上,必要時還可使用參加eventData向事件處理程序傳遞數據。對象

.live()方法是基本的.bind()方法的一個變形,後者能夠將事件處理程序附加到 元素·,當調用.bind()時,jQuery對象匹配的元素將被附加上事件處理程序,但之後添加的元素並不會被附加該事件處理程序,所以,還須要對這些 元素再次調用.bind()方法。

.one()方法將事件處理程序附加到匹配元素的指定事件並返回jQuery對象。所附加的事件處理程序最多隻能執行一次。

.one(eventType,[eventData],handler(eventObject))

其中,參數eventType是一個字符串,包含一個或多個javaScript事件類 型,例如click,submit或自定義事件的名稱,指定多個事件類型時用空格分隔各個類型;eventData爲Map類型,給出要傳遞給事件處理程 序的數據,handler指定觸發該事件時要執行的函數,eventObject表示事件對象。

.one()方法與.bind()相似,所不一樣的是,使用.one()綁定的事件處理程序在執行一次以後將自動取消綁定。

.delegate()方法基於一組特定的根元素將處理程序附加到匹配選擇器的全部元素(現有的或未來的)的一個或多個事件上。

.delegate(selector,eventType[,eventData],handler)

其中,參數 selector是一個選擇器,用於篩選觸發事件的元素;eventType是一個字符串,指定一個或多個JavaScript事件類型(多個事件用空格 分隔),例如click,keydown或自定義事件名稱;eventData爲映射類型,表示要傳遞給事件處理程序的數據;handler表示觸發該事 件時執行的函數。

.delegate()與.live()相似,可將每一個事件的綁定委託給指定的DOM元素。

 

再說說區別:

  • bind是在dom樹加載後,對元素的綁定,屬於後期綁定。

  • one是在dom樹加載後,對元素的綁定,和bind同樣屬於後期綁定,可是會在事件執行以後移除元素的綁定事件,事件只執行一次。

  • live 是先把事件綁定在document對象上面,經過事件冒泡,判斷當前處於目標狀態的元素是否是預綁定的那個元素對象,而後執行事件,屬於前期綁定,元素能夠是已存在的,也能夠是動態添加的。

  • delegate綁定的元素能夠是已經存在的,也能夠是動態添加的。若是是已經存在的就會選定一個父元素,經過冒泡來觸發指定子元素的事件。若是是動態添加的,就以document爲父元素來觸發冒泡事件。

  • (注:這裏所說的後期綁定指的是元素已經加載後,進行事件的綁定。前期綁定指的是元素還沒有存在,爲動態元素添加事件)

     這幾種方法推薦使用binddelegate,由於live是綁定事件在document上面,而後經過冒泡查詢元素執行事件,很耗性能。

 

      它們的原生js實現 :

     

複製代碼
        (function (context) {
            var _$ = function (selector) {
                return new _$.prototype.Init(selector);
            }
            _$.prototype = {
                Init: function () {
                    var arr = Array.prototype.slice.call(arguments);
                    if (arr.length > 0)
                    {
                        if (typeof arr[0] == "string") {
                            this.element = document.getElementById(arr[0]);
                        }
                        else if (Object.prototype.toString.call(arr[0])=="object Object") {
                            this.element = arr[0];
                        }
                    }

                },
                bind: function (type, fn) {
                    if (this.element) {
                        if (document.addEventListener) {
                            this.element.addEventListener(type, fn, false);
                        }
                        else if (document.attachEvent) {
                            this.element.attachEvent('on' + type, fn);
                        }
                        else {
                            this.element['on' + type] = fn;
                        }
                    }
                },
                unbind: function (type, fn) {
                    if (this.element) {
                        if (document.removeEventListener) {
                            this.element.removeEventListener(type, fn, false);
                        }
                        else if (document.attachEvent) {
                            this.element.detachEvent('on' + type, fn);
                        }
                        else {
                            this.element['on' + type] = null;
                        }
                    }
                },
                one: function (type, fn) {
                    var self = this;
                    if (this.element) {
                        if (document.addEventListener) {
                            this.element.addEventListener(type, function () {
                                self.element.removeEventListener(type, arguments.callee, false);
                                fn();
                            }, false);
                        }
                        else if (document.attachEvent) {
                            this.element.attachEvent('on' + type, function () {
                                self.element.detachEvent('on' + type, arguments.callee);
                                fn();
                            });
                        }
                        else {
                            this.element['on' + type] = function () {
                                self.element['on' + type] = null;
                                fn();
                            };
                        }
                    }

                },
                live: function (type, fn) {
                    var self = this;
                    if (document.addEventListener) {
                        document.addEventListener(type, function (e) {
                            var evt = e || window.event;
                            var target = evt.srcElement || evt.target;
                            if (target.id == self.element.id) {
                                fn();
                            }
                        }, false);
                    }
                    else if (document.attachEvent) {
                        document.attachEvent('on' + type, function (e) {
                            var evt = e || window.event;
                            var target = evt.srcElement || evt.target;
                            if (target.id == self.element.id) {
                                fn();
                            }
                        });
                    }
                    else {
                        document['on' + type] = function (e) {
                            var evt = e || window.event;
                            var target = evt.srcElement || evt.target;
                            if (target.id == self.element.id) {
                                document['on' + type] = null;
                                fn();
                            }
                        };
                    }
                },
                delegate: function (flag, type, fn) {
                    var self = this;
                    if (document.addEventListener) {
                        self.element.addEventListener(type, function (e) {
                            var evt = e || window.event;
                            var target = evt.srcElement || evt.target;
                            if (target.tagName.toLowerCase() == flag) {
                                fn();
                            }
                        }, false);
                    }
                    else if (document.attachEvent) {
                        self.element.attachEvent('on' + type, function (e) {
                            var evt = e || window.event;
                            var target = evt.srcElement || evt.target;
                            if (target.tagName.toLowerCase() == flag) {
                                fn();
                            }
                        });
                    }
                    else {
                        self.element['on' + type] = function (e) {
                            var evt = e || window.event;
                            var target = evt.srcElement || evt.target;
                            if (target.tagName.toLowerCase() == flag) {
                                fn();
                            }
                        };
                    }



                }

            }
            _$.prototype.Init.prototype = _$.prototype;

            context.$ = _$;
        })(window);
複製代碼

     這裏就是一些兼容性代碼,閱讀起來沒啥難度,若是有描述不清楚的地方,能夠留言。

相關文章
相關標籤/搜索