亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

原生js實(shí)現(xiàn)on與off 方法

tanglijun / 955人閱讀

摘要:所以僅對(duì)參數(shù)進(jìn)行了處理,功能上沒有實(shí)現(xiàn)子選擇器事件觸發(fā)后執(zhí)行的函數(shù)指定事件是否在捕獲或冒泡階段執(zhí)行事件句柄在捕獲階段執(zhí)行默認(rèn)。

使用過jQuery的同學(xué),應(yīng)該對(duì)事件綁定方法 .on() .off() 有一定的了解。 在個(gè)人類庫jTool 中實(shí)現(xiàn)了這兩個(gè)方法,這里就來細(xì)說下原生實(shí)現(xiàn)方式。
實(shí)現(xiàn)方式
以下為個(gè)人類庫jTool 中 Event 實(shí)現(xiàn)方式。
代碼中使用到一個(gè)基礎(chǔ)方法對(duì)象utilities ,該對(duì)象為jTool 的基礎(chǔ)類。 如果想了解更多,可以通過點(diǎn)擊進(jìn)入查看原碼。
一個(gè)空殼子
首先通過一個(gè)空架子來了解下實(shí)現(xiàn)邏輯,核心實(shí)現(xiàn)在getEventObject() 方法內(nèi)的包裝函數(shù)
var Event = {
    // 綁定
    on: function(event, querySelector, callback, useCapture){
        return this.addEvent(this.getEventObject(event, querySelector, callback, useCapture));
    },
    // 解除綁定
    off: function(event, querySelector) {
        return this.removeEvent(this.getEventObject(event, querySelector));
    },
    // 獲取 jTool Event 對(duì)象
    getEventObject: function (event, querySelector, callback, useCapture){
        // 事件代理實(shí)現(xiàn)核心
        // 注意: 這個(gè)方法為包裝函數(shù),此處的this為觸發(fā)事件的Element
        var fn = callback;
            callback = function(e){
                // 驗(yàn)證子選擇器所匹配的nodeList中是否包含當(dāng)前事件源 或 事件源的父級(jí)
                // 注意: 這個(gè)方法為包裝函數(shù),此處的this為觸發(fā)事件的Element
                var target = e.target;
                while(target !== this ){
                    if([].indexOf.call( this.querySelectorAll(querySelector), target) !== -1){
                        fn.apply(target, arguments);
                        break;
                    }
                    target = target.parentNode;
                }
            };
    
        return {
                eventName: event + querySelector,
                type: event,
                querySelector: querySelector,
                callback: callback || utilities.noop,
                useCapture: useCapture || false
            };
    },
    // 增加事件,并將事件對(duì)象存儲(chǔ)至DOM節(jié)點(diǎn)
    addEvent: function (eventList){
    },
    // 刪除事件,并將事件對(duì)象移除出DOM節(jié)點(diǎn)
    removeEvent: function (eventList){
    
    }
}
參數(shù)說明

event: 事件名, 如 "click", 并支持 "click.scope1" 事件域的方法(雖然支持,但由于暫時(shí)沒有使用場(chǎng)景。所以僅對(duì)參數(shù)進(jìn)行了處理,功能上沒有實(shí)現(xiàn))

querySelector: 子選擇器

callback: 事件觸發(fā)后執(zhí)行的函數(shù)

useCapture: 指定事件是否在捕獲或冒泡階段執(zhí)行.true - 事件句柄在捕獲階段執(zhí)行 false- 默認(rèn)。事件句柄在冒泡階段執(zhí)行

eventList: 由 .getEventObject() 方法生成的 Event 對(duì)象,

on的實(shí)現(xiàn)邏輯

通過調(diào)用jTool實(shí)例的on方法,傳入?yún)?shù)

調(diào)用getEventObject() 獲取事件對(duì)象

調(diào)用addEvent() 方法進(jìn)行事件綁定

off的實(shí)現(xiàn)邏輯

通過調(diào)用jTool實(shí)例的off方法,傳入?yún)?shù)

調(diào)用getEventObject()獲取事件對(duì)象

調(diào)用removeEvent()方法解除事件綁定

完整Event對(duì)象
var _Event = {
    on: function(event, querySelector, callback, useCapture) {
        // 將事件觸發(fā)執(zhí)行的函數(shù)存儲(chǔ)于DOM上, 在清除事件時(shí)使用
    },
    
    off: function(event, querySelector) {
        return this.removeEvent(this.getEventObject(event, querySelector));
    },
    
    bind: function(event, callback, useCapture) {
        return this.on(event, undefined, callback, useCapture);
    },
    
    unbind: function(event) {
        return this.removeEvent(this.getEventObject(event));
    },
    // 獲取 jTool Event 對(duì)象
    getEventObject: function(event, querySelector, callback, useCapture) {
        // $(dom).on(event, callback);
        if (typeof querySelector === "function") {
            useCapture = callback || false;
            callback = querySelector;
            querySelector = undefined;
        }
        // event callback 為必要參數(shù)
        if (!event) {
            utilities.error("事件綁定失敗,原因: 參數(shù)中缺失事件類型");
            return this;
        }
    
        // 子選擇器不存在 或 當(dāng)前DOM對(duì)象包含Window Document 則將子選擇器置空
        if(!querySelector || utilities.type(this.DOMList[0]) !== "element"){
            querySelector = "";
        }
        // #Event003 存在子選擇器 -> 包裝回調(diào)函數(shù), 回調(diào)函數(shù)的參數(shù)
        // 預(yù)綁定功能實(shí)現(xiàn)
        if(querySelector !== ""){
            var fn = callback;
            callback = function(e){
                // 驗(yàn)證子選擇器所匹配的nodeList中是否包含當(dāng)前事件源 或 事件源的父級(jí)
                // 注意: 這個(gè)方法為包裝函數(shù),此處的this為觸發(fā)事件的Element
                var target = e.target;
                while(target !== this ){
                    if([].indexOf.call( this.querySelectorAll(querySelector), target) !== -1){
                        fn.apply(target, arguments);
                        break;
                    }
                    target = target.parentNode;
                }
            };
        }
        var eventSplit = event.split(" ");
        var eventList = [],
            eventScopeSplit,
            eventObj;
    
        utilities.each(eventSplit, function(i, eventName) {
            if (eventName.trim() === "") {
                return true;
            }
    
            eventScopeSplit = eventName.split(".");
            eventObj = {
                eventName: eventName + querySelector,
                type: eventScopeSplit[0],
                querySelector: querySelector,
                callback: callback || utilities.noop,
                useCapture: useCapture || false,
                // TODO: nameScope暫時(shí)不用
                nameScope: eventScopeSplit[1] || undefined
            };
            eventList.push(eventObj);
        });
        return eventList;
    },
    
    // 增加事件,并將事件對(duì)象存儲(chǔ)至DOM節(jié)點(diǎn)
    addEvent: function(eventList) {
        var _this = this;
        utilities.each(eventList, function (index, eventObj) {
            utilities.each(_this.DOMList, function(i, v){
                v.jToolEvent = v.jToolEvent || {};
                v.jToolEvent[eventObj.eventName] = v.jToolEvent[eventObj.eventName] || [];
                v.jToolEvent[eventObj.eventName].push(eventObj);
                v.addEventListener(eventObj.type, eventObj.callback, eventObj.useCapture);
            });
        });
        return _this;
    },
    
    // 刪除事件,并將事件對(duì)象移除出DOM節(jié)點(diǎn)
    removeEvent: function(eventList) {
        var _this = this;
        var eventFnList; //事件執(zhí)行函數(shù)隊(duì)列
        utilities.each(eventList, function(index, eventObj) {
            utilities.each(_this.DOMList, function(i, v){
                if (!v.jToolEvent) {
                    return;
                }
                eventFnList = v.jToolEvent[eventObj.eventName];
                if (eventFnList) {
                    utilities.each(eventFnList, function(i2, v2) {
                        v.removeEventListener(v2.type, v2.callback);
                    });
                    v.jToolEvent[eventObj.eventName] = undefined;
                }
            });
        });
        return _this;
    }
};

.on().bind()都可以進(jìn)行事件綁定, 區(qū)別在于.on()使用事件代理。 事件代理是一種事件預(yù)綁定機(jī)制, 該機(jī)制可以在事件節(jié)點(diǎn)不存在的情況下, 將事件綁定至已存在父級(jí)節(jié)點(diǎn)之上的方式。

隨筆一行
這是前端最好的時(shí)代, 這也是前端最壞的時(shí)代。 眾多前端框架滿天飛,隨著 jQuery 在前端行業(yè)的慢慢弱化,總是會(huì)有一種斯人遠(yuǎn)去,何者慰籍的感覺?;ッ惆?,各位。

另推薦個(gè)表格組件gridManager

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/109774.html

相關(guān)文章

  • 前端培訓(xùn)-中級(jí)階段(6)- jQuery的事件綁定鏈?zhǔn)讲僮骷霸恚?019-07-25期)

    摘要:前端最基礎(chǔ)的就是。幫助從舊的事件方法轉(zhuǎn)換,和。方法移除用綁定的事件處理程序。特定的事件處理程序可以被移除元素上提供事件名稱,命名空間,處理函數(shù)。用于過濾器的觸發(fā)事件的選擇器元素的后代。事件觸發(fā)模擬觸發(fā)原生使用觸發(fā)。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS)...

    Airy 評(píng)論0 收藏0
  • 前端培訓(xùn)-中級(jí)階段(6)- jQuery的事件綁定鏈?zhǔn)讲僮骷霸恚?019-07-25期)

    摘要:前端最基礎(chǔ)的就是。幫助從舊的事件方法轉(zhuǎn)換,和。方法移除用綁定的事件處理程序。特定的事件處理程序可以被移除元素上提供事件名稱,命名空間,處理函數(shù)。用于過濾器的觸發(fā)事件的選擇器元素的后代。事件觸發(fā)模擬觸發(fā)原生使用觸發(fā)。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS)...

    sutaking 評(píng)論0 收藏0
  • jQuery 事件(三) 事件的綁定和解綁、對(duì)象的使用、自定義事件

    摘要:事件的綁定和解綁的多事件綁定之前學(xué)的鼠標(biāo)事件,表單事件與鍵盤事件都有個(gè)特點(diǎn),就是直接給元素綁定一個(gè)處理函數(shù),所有這類事件都是屬于快捷處理。由于瀏覽器事件冒泡特性,可以在觸發(fā)時(shí)把這個(gè)事件往上冒泡到上,因?yàn)樯辖壎ㄊ录憫?yīng),所以能觸發(fā)這個(gè)動(dòng)作。 事件的綁定和解綁 on()的多事件綁定 之前學(xué)的鼠標(biāo)事件,表單事件與鍵盤事件都有個(gè)特點(diǎn),就是直接給元素綁定一個(gè)處理函數(shù),所有這類事件都是屬于快捷處理...

    niuxiaowei111 評(píng)論0 收藏0
  • 瀑布流插件Masonry中文文檔【翻譯】

    摘要:本位為官方文檔翻譯,原始鏈接安裝下載下載壓縮或未壓縮的壓縮未壓縮在直接飲用文件。排列未加載完成的圖片時(shí)會(huì)導(dǎo)致元素的重疊,可以解決這個(gè)問題。布局組件尺寸尺寸配置項(xiàng)和可以可以設(shè)置組件的列寬和間距。增加移除控件在瀑布流末尾增加新控件并重排。 本位為Masonry官方文檔翻譯,原始鏈接 安裝Install 下載 下載壓縮或未壓縮的masonry masonry.pkgd.min.js (壓縮...

    soasme 評(píng)論0 收藏0
  • 原生JS實(shí)現(xiàn)粘貼到剪貼板

    摘要:綜上加兩行如果不是等表單元素,不能使用和的話,那么我們可以使用和方法來模擬這個(gè)過程了,對(duì)象表示用戶選擇的文本范圍或光標(biāo)的當(dāng)前位置,滿足執(zhí)行命令的可編輯活動(dòng)區(qū)域,如下上述針對(duì)非,等表單元素也能實(shí)現(xiàn)了 本文主要討論原生方法 目前常見的實(shí)現(xiàn)粘貼到剪貼板主要有以下兩種方法: 第三方庫 clipboard 原生JS, 主要是 document.execCommand方法 第一種方法按照文檔...

    Pikachu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<