摘要:所以僅對參數進行了處理,功能上沒有實現子選擇器事件觸發后執行的函數指定事件是否在捕獲或冒泡階段執行事件句柄在捕獲階段執行默認。
使用過jQuery的同學,應該對事件綁定方法 .on() .off() 有一定的了解。 在個人類庫jTool 中實現了這兩個方法,這里就來細說下原生實現方式。實現方式
以下為個人類庫jTool 中 Event 實現方式。一個空殼子
代碼中使用到一個基礎方法對象utilities ,該對象為jTool 的基礎類。 如果想了解更多,可以通過點擊進入查看原碼。
首先通過一個空架子來了解下實現邏輯,核心實現在getEventObject() 方法內的包裝函數
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 對象 getEventObject: function (event, querySelector, callback, useCapture){ // 事件代理實現核心 // 注意: 這個方法為包裝函數,此處的this為觸發事件的Element var fn = callback; callback = function(e){ // 驗證子選擇器所匹配的nodeList中是否包含當前事件源 或 事件源的父級 // 注意: 這個方法為包裝函數,此處的this為觸發事件的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 }; }, // 增加事件,并將事件對象存儲至DOM節點 addEvent: function (eventList){ }, // 刪除事件,并將事件對象移除出DOM節點 removeEvent: function (eventList){ } }參數說明
event: 事件名, 如 "click", 并支持 "click.scope1" 事件域的方法(雖然支持,但由于暫時沒有使用場景。所以僅對參數進行了處理,功能上沒有實現)
querySelector: 子選擇器
callback: 事件觸發后執行的函數
useCapture: 指定事件是否在捕獲或冒泡階段執行.true - 事件句柄在捕獲階段執行 false- 默認。事件句柄在冒泡階段執行
eventList: 由 .getEventObject() 方法生成的 Event 對象,
on的實現邏輯通過調用jTool實例的on方法,傳入參數
調用getEventObject() 獲取事件對象
調用addEvent() 方法進行事件綁定
off的實現邏輯通過調用jTool實例的off方法,傳入參數
調用getEventObject()獲取事件對象
調用removeEvent()方法解除事件綁定
完整Event對象var _Event = { on: function(event, querySelector, callback, useCapture) { // 將事件觸發執行的函數存儲于DOM上, 在清除事件時使用 }, 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 對象 getEventObject: function(event, querySelector, callback, useCapture) { // $(dom).on(event, callback); if (typeof querySelector === "function") { useCapture = callback || false; callback = querySelector; querySelector = undefined; } // event callback 為必要參數 if (!event) { utilities.error("事件綁定失敗,原因: 參數中缺失事件類型"); return this; } // 子選擇器不存在 或 當前DOM對象包含Window Document 則將子選擇器置空 if(!querySelector || utilities.type(this.DOMList[0]) !== "element"){ querySelector = ""; } // #Event003 存在子選擇器 -> 包裝回調函數, 回調函數的參數 // 預綁定功能實現 if(querySelector !== ""){ var fn = callback; callback = function(e){ // 驗證子選擇器所匹配的nodeList中是否包含當前事件源 或 事件源的父級 // 注意: 這個方法為包裝函數,此處的this為觸發事件的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暫時不用 nameScope: eventScopeSplit[1] || undefined }; eventList.push(eventObj); }); return eventList; }, // 增加事件,并將事件對象存儲至DOM節點 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; }, // 刪除事件,并將事件對象移除出DOM節點 removeEvent: function(eventList) { var _this = this; var eventFnList; //事件執行函數隊列 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()都可以進行事件綁定, 區別在于.on()使用事件代理。 事件代理是一種事件預綁定機制, 該機制可以在事件節點不存在的情況下, 將事件綁定至已存在父級節點之上的方式。
隨筆一行
這是前端最好的時代, 這也是前端最壞的時代。 眾多前端框架滿天飛,隨著 jQuery 在前端行業的慢慢弱化,總是會有一種斯人遠去,何者慰籍的感覺。互勉吧,各位。
另推薦個表格組件gridManager
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109774.html
摘要:前端最基礎的就是。幫助從舊的事件方法轉換,和。方法移除用綁定的事件處理程序。特定的事件處理程序可以被移除元素上提供事件名稱,命名空間,處理函數。用于過濾器的觸發事件的選擇器元素的后代。事件觸發模擬觸發原生使用觸發。 前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,現在前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS)...
摘要:前端最基礎的就是。幫助從舊的事件方法轉換,和。方法移除用綁定的事件處理程序。特定的事件處理程序可以被移除元素上提供事件名稱,命名空間,處理函數。用于過濾器的觸發事件的選擇器元素的后代。事件觸發模擬觸發原生使用觸發。 前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,現在前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS)...
摘要:事件的綁定和解綁的多事件綁定之前學的鼠標事件,表單事件與鍵盤事件都有個特點,就是直接給元素綁定一個處理函數,所有這類事件都是屬于快捷處理。由于瀏覽器事件冒泡特性,可以在觸發時把這個事件往上冒泡到上,因為上綁定事件響應,所以能觸發這個動作。 事件的綁定和解綁 on()的多事件綁定 之前學的鼠標事件,表單事件與鍵盤事件都有個特點,就是直接給元素綁定一個處理函數,所有這類事件都是屬于快捷處理...
摘要:本位為官方文檔翻譯,原始鏈接安裝下載下載壓縮或未壓縮的壓縮未壓縮在直接飲用文件。排列未加載完成的圖片時會導致元素的重疊,可以解決這個問題。布局組件尺寸尺寸配置項和可以可以設置組件的列寬和間距。增加移除控件在瀑布流末尾增加新控件并重排。 本位為Masonry官方文檔翻譯,原始鏈接 安裝Install 下載 下載壓縮或未壓縮的masonry masonry.pkgd.min.js (壓縮...
摘要:綜上加兩行如果不是等表單元素,不能使用和的話,那么我們可以使用和方法來模擬這個過程了,對象表示用戶選擇的文本范圍或光標的當前位置,滿足執行命令的可編輯活動區域,如下上述針對非,等表單元素也能實現了 本文主要討論原生方法 目前常見的實現粘貼到剪貼板主要有以下兩種方法: 第三方庫 clipboard 原生JS, 主要是 document.execCommand方法 第一種方法按照文檔...
閱讀 2463·2021-09-28 09:36
閱讀 3606·2021-09-22 15:41
閱讀 4407·2021-09-04 16:45
閱讀 1988·2019-08-30 15:55
閱讀 2850·2019-08-30 13:49
閱讀 829·2019-08-29 16:34
閱讀 2376·2019-08-29 12:57
閱讀 1685·2019-08-26 18:42