摘要:事件模型事件模型共有兩個(gè)過程事件處理階段。事件綁定監(jiān)聽函數(shù)的方式如下事件移除監(jiān)聽函數(shù)的方式如下參數(shù)說明指定事件類型注意加是事件處理函數(shù)級(jí)模型屬于標(biāo)準(zhǔn)模型,現(xiàn)代瀏覽器除之外的瀏覽器都支持該模型。
JS事件模型 觀察者模式
觀察者模式又叫做發(fā)布訂閱者模式(Publish/Subscribe),它可以讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象,這個(gè)主題對(duì)象的狀態(tài)變化時(shí)會(huì)通知所有的訂閱者,使得它們能夠做出反應(yīng)。
JS的事件模型就是一種觀察者模式的體現(xiàn),當(dāng)對(duì)應(yīng)的事件被觸發(fā)時(shí),監(jiān)聽該事件的所有監(jiān)聽函數(shù)都會(huì)被調(diào)用。
下面是用JS實(shí)現(xiàn)的一個(gè)觀察者模式的代碼:
var events = (function() { var topics = {}; return { publish: function(topic, info) { console.log("publish a topic:" + topic); if (topics.hasOwnProperty(topic)) { topics[topic].forEach(function(handler) { handler(info ? info : {}); }) } }, subscribe: function(topic, handler) { console.log("subscribe an topic:" + topic); if (!topics.hasOwnProperty(topic)) { topics[topic] = []; } topics[topic].push(handler); }, remove: function(topic, handler) { if (!topics.hasOwnProperty(topic)) { return; } var handlerIndex = -1; topics[topic].forEach(function(element, index) { if (element === handler) { handlerIndex = index; } }); if (handlerIndex >= 0) { topics[topic].splice(handlerIndex, 1); } }, removeAll: function(topic) { console.log("remove all the handler on the topic:" + topic); if (topics.hasOwnProperty(topic)) { topics[topic].length = 0; } } } })();
使用事例:
//主題監(jiān)聽函數(shù) var handler = function(info) { console.log(info); } //訂閱hello主題 events.subscribe("hello", handler); //發(fā)布hello主題 events.publish("hello", "hello world");事件與事件流
事件是與瀏覽器或文檔交互的瞬間,如點(diǎn)擊按鈕,填寫表格等,它是JS與HTML之間交互的橋梁。
DOM是樹形結(jié)構(gòu),如果同時(shí)給父子節(jié)點(diǎn)都綁定事件時(shí),當(dāng)觸發(fā)子節(jié)點(diǎn)的時(shí)候,這兩個(gè)事件的發(fā)生順序如何決定?這就涉及到事件流的概念,它描述的是頁面中接受事件的順序。
事件流有兩種:
事件冒泡(Event Capturing): 是一種從下往上的傳播方式。事件最開始由最具體的元素(文檔中嵌套層次最深的那個(gè)節(jié)點(diǎn)接受, 也就是DOM最低層的子節(jié)點(diǎn)), 然后逐漸向上傳播到最不具體的那個(gè)節(jié)點(diǎn),也就是DOM中最高層的父節(jié)點(diǎn)。
事件捕獲(Event Bubbling): 與事件冒泡相反。事件最開始由不太具體的節(jié)點(diǎn)最早接受事件, 而最具體的節(jié)點(diǎn)最后接受事件。
事件模型 DOM0級(jí)模型又稱為原始事件模型,在該模型中,事件不會(huì)傳播,即沒有事件流的概念。事件綁定監(jiān)聽函數(shù)比較簡單, 有兩種方式:
HTML代碼中直接綁定:
通過JS代碼指定屬性值:
var btn = document.getElementById(".btn"); btn.onclick = fun;
移除監(jiān)聽函數(shù):
btn.onclick = null;
這種方式所有瀏覽器都兼容,但是邏輯與顯示并沒有分離。
IE事件模型IE事件模型共有兩個(gè)過程:
事件處理階段(target phase)。事件到達(dá)目標(biāo)元素, 觸發(fā)目標(biāo)元素的監(jiān)聽函數(shù)。
事件冒泡階段(bubbling phase)。事件從目標(biāo)元素冒泡到document, 依次檢查經(jīng)過的節(jié)點(diǎn)是否綁定了事件監(jiān)聽函數(shù),如果有則執(zhí)行。
事件綁定監(jiān)聽函數(shù)的方式如下:
attachEvent(eventType, handler)
事件移除監(jiān)聽函數(shù)的方式如下:
detachEvent(eventType, handler)
參數(shù)說明:
eventType指定事件類型(注意加on)
handler是事件處理函數(shù)
Example:
var btn = document.getElementById(".btn"); btn.attachEvent(‘onclick’, showMessage); btn.detachEvent(‘onclick’, showMessage);DOM2級(jí)模型
屬于W3C標(biāo)準(zhǔn)模型,現(xiàn)代瀏覽器(除IE6-8之外的瀏覽器)都支持該模型。在該事件模型中,一次事件共有三個(gè)過程:
事件捕獲階段(capturing phase)。事件從document一直向下傳播到目標(biāo)元素, 依次檢查經(jīng)過的節(jié)點(diǎn)是否綁定了事件監(jiān)聽函數(shù),如果有則執(zhí)行。
事件處理階段(target phase)。事件到達(dá)目標(biāo)元素, 觸發(fā)目標(biāo)元素的監(jiān)聽函數(shù)。
事件冒泡階段(bubbling phase)。事件從目標(biāo)元素冒泡到document, 依次檢查經(jīng)過的節(jié)點(diǎn)是否綁定了事件監(jiān)聽函數(shù),如果有則執(zhí)行。
事件綁定監(jiān)聽函數(shù)的方式如下:
addEventListener(eventType, handler, useCapture)
事件移除監(jiān)聽函數(shù)的方式如下:
removeEventListener(eventType, handler, useCapture)
Example:
var btn = document.getElementById(".btn"); btn.addEventListener(‘click’, showMessage, false); btn.removeEventListener(‘click’, showMessage, false);
參數(shù)說明:
eventType指定事件類型(不要加on)
handler是事件處理函數(shù)
useCapture是一個(gè)boolean用于指定是否在捕獲階段進(jìn)行處理,一般設(shè)置為false與IE瀏覽器保持一致。
事件對(duì)象當(dāng)一個(gè)事件被觸發(fā)時(shí),會(huì)創(chuàng)建一個(gè)事件對(duì)象(Event Object), 這個(gè)對(duì)象里面包含了與該事件相關(guān)的屬性或者方法。該對(duì)象會(huì)作為第一個(gè)參數(shù)傳遞給監(jiān)聽函數(shù)。
DOM事件模型中的事件對(duì)象常用屬性:
type用于獲取事件類型
target獲取事件目標(biāo)
stopPropagation()阻止事件冒泡
preventDefault()阻止事件默認(rèn)行為
IE事件模型中的事件對(duì)象常用屬性:
type用于獲取事件類型
srcElement獲取事件目標(biāo)
cancelBubble阻止事件冒泡
returnValue阻止事件默認(rèn)行為
Event Wrapper由于事件模型的差異以及Event對(duì)象的不同,為了達(dá)到兼容各個(gè)瀏覽器的目的,我們可以增加一個(gè)Event Wrapper, 它對(duì)各個(gè)瀏覽器應(yīng)當(dāng)提供一致的事件操作接口。
var eventUtils={ // 添加句柄 addHandler:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent("on"+type,handler); }else{ element["on"+type]=handler; } }, // 刪除句柄 removeHandler:function(element,type,handler){ if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else if(element.detachEvent){ element.detachEvent("on"+type,handler); }else{ element["on"+type]=null; } }, //獲取事件對(duì)象 //IE模型中event是一個(gè)全局唯一的對(duì)象綁定在window對(duì)象上 getEvent:function(event){ return event?event:window.event; }, //獲取類型 getType:function(event){ return event.type; }, getElement:function(event){ return event.target || event.srcElement; }, //阻止默認(rèn)事件 preventDefault:function(event){ if(event.preventDefault){ event.preventDefault(); }else{ event.returnValue=false; } }, //阻止冒泡 stopPropagation:function(event){ if(event.stopPropagation){ event.stopPropagation(); }else{ event.cancelBubble=true; } } }
參考:
DOM事件揭秘
事件代理事件在冒泡過程中會(huì)上傳到父節(jié)點(diǎn),因此可以把子節(jié)點(diǎn)的監(jiān)聽函數(shù)定義在父節(jié)點(diǎn)上,由父節(jié)點(diǎn)的監(jiān)聽函數(shù)統(tǒng)一處理多個(gè)子元素的事件,這種方式稱為事件代理(Event delegation)。
我們有一個(gè)div元素,它包含三個(gè)按鈕:
我們可以在父節(jié)點(diǎn)上一次性的為所有子節(jié)點(diǎn)注冊(cè)監(jiān)聽函數(shù):
var box = document.getElementById("box"); box.addEventListener("click", function(event) { if (event.target.tagName.toLowerCase() === "input") { // some code } });自定義事件
JS中已經(jīng)內(nèi)置了很多事件,如click, mouseover等等,但是內(nèi)置事件畢竟有限,有時(shí)候我們想自己定義一些事件,例如三連擊,threeclick。如何實(shí)現(xiàn)自定義事件呢?
首先要?jiǎng)?chuàng)建一個(gè)事件。可以使用以下方式:
var event = new Event("threeclick", {"bubbles":true, "cancelable":false});
然后我們需要為事件注冊(cè)監(jiān)聽函數(shù):
target.addEventListener("threeclick", hello, false);
最后我們要在合適的時(shí)機(jī)觸發(fā)該事件,我們可以使用dispatchEvent函數(shù)。該方法在當(dāng)前節(jié)點(diǎn)觸發(fā)指定事件,從而觸發(fā)監(jiān)聽函數(shù)執(zhí)行。該方法返回一個(gè)布爾值,只要有一個(gè)監(jiān)聽函數(shù)調(diào)用了Event.preventDefault(), 則返回false, 否則返回true。
target.dispatchEvent(event);JQuery Event模型
JQuery解決的一個(gè)主要問題就是瀏覽器的兼容問題,它有自己的事件模型實(shí)現(xiàn)方式。它主要有以下特性:
重定義了JQuery.Event對(duì)象, 統(tǒng)一了事件屬性和方法, 統(tǒng)一了事件模型
可以在一個(gè)事件類型上添加多個(gè)事件處理函數(shù), 可以一次添加多個(gè)事件類型的事件處理函數(shù)
支持自定義事件(事件命名空間)
提供了toggle, hover組合事件
提供了one, live-die, delegate-undelegate
提供了統(tǒng)一的事件封裝, 綁定, 執(zhí)行, 銷毀機(jī)制
$(document).ready();
....
JQuery事件具體代碼請(qǐng)參考: https://github.com/jquery/jqu...
JQuery事件具體使用方式請(qǐng)自行查找
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/80388.html
摘要:它通過數(shù)據(jù)模型進(jìn)行鍵值綁定及事件處理,通過模型集合器提供一套豐富的用于枚舉功能,通過視圖來進(jìn)行事件處理及與現(xiàn)有的通過接口進(jìn)行交互。 本人兼職前端付費(fèi)技術(shù)顧問,如需幫助請(qǐng)加本人微信hawx1993或QQ345823102,非誠勿擾 1.為初學(xué)前端而不知道怎么做項(xiàng)目的你指導(dǎo) 2.指導(dǎo)并扎實(shí)你的JavaScript基礎(chǔ) 3.幫你準(zhǔn)備面試并提供相關(guān)指導(dǎo)性意見 4.為你的前端之路提供極具建設(shè)性的...
摘要:取消事件的默認(rèn)行為。阻止事件的派發(fā)包括了捕獲和冒泡阻止同一個(gè)事件的其他監(jiān)聽函數(shù)被調(diào)用。 事件模型 DOM0 級(jí)事件模型 -沒有事件流,這種方式兼容所有瀏覽器 // 方式一 將事件直接通過屬性綁定在元素上 / 方式二 獲取到頁面元素后,通過 onclick 等事件,將觸發(fā)的方法指定為元素的事件 var btn = document.getElementById(btn) btn....
摘要:在這個(gè)事件發(fā)生期間,調(diào)用可阻止?jié)L動(dòng)當(dāng)手指從屏幕上移開時(shí)觸發(fā)。關(guān)于此事件的確切觸發(fā)事件,文檔中沒有明確說明。特定于事件目標(biāo)的對(duì)象的數(shù)組。 JS事件模型 事件模型以及周邊 事件捕獲 事件冒泡 事件觸發(fā) 移動(dòng)端事件模擬 事件委托 事件流 事件捕獲(event capturing)&事件冒泡(event bubbling) 給inner,out均綁定點(diǎn)擊事件.點(diǎn)擊inne...
摘要:兩個(gè)事件驅(qū)動(dòng)模型服務(wù)器平均每秒處理的請(qǐng)求數(shù)為服務(wù)器的一倍,而內(nèi)存降低了一半。事件驅(qū)動(dòng)模型的出現(xiàn),是為了解決傳統(tǒng)服務(wù)器與網(wǎng)絡(luò)工作負(fù)載的需求的不匹配,實(shí)現(xiàn)高度可伸縮服務(wù)器,并降低內(nèi)存開銷。 from http://oyanglul.us 本文基本上這為兩篇文章的翻譯和整合 -...
摘要:在內(nèi)聯(lián)模型中,事件處理函數(shù)是標(biāo)簽的一個(gè)屬性,用于處理指定事件。事件捕獲與冒泡原理圖事件流同時(shí)支持兩種事件模型捕獲型事件和冒泡型事件,但是,捕獲型事件先發(fā)生。 javascript -- 事件 事件是js和用戶操作交互的橋梁, JavaScript 有三種事件模型:內(nèi)聯(lián)模型、腳本模型和 DOM2 模型 內(nèi)聯(lián)模型 這種模型是最傳統(tǒng)接單的一種處理事件的方法。在內(nèi)聯(lián)模型中,事件處理函數(shù)是 HT...
閱讀 1407·2021-09-02 09:53
閱讀 2671·2021-07-29 13:50
閱讀 1720·2019-08-30 11:07
閱讀 1574·2019-08-30 11:00
閱讀 1456·2019-08-29 14:00
閱讀 1851·2019-08-29 12:52
閱讀 2566·2019-08-29 11:11
閱讀 3425·2019-08-26 12:23