JavaScript事件

1.事件流

1.1事件冒泡

IE的事件流叫做事件冒泡,事件開始時由最具體的元素節(jié)點接收,逐步向上傳播。

<!DOCTYPE html>
<html>
<head>
    <title>Event Bubbling Example</title>
</head>
<body>
    <div id="myDiv">Click Me</div>
</body>
</html>

如果你在div設(shè)置了一個點擊事件,則傳播順序:1.div 2.body 3.html 4.document

1.2 事件捕獲

不太具體的節(jié)點應(yīng)該更早的接收事件。在事件達(dá)到預(yù)期目標(biāo)之前捕獲它。
仍然是上面的例子,事件捕獲順序:1.document 2.html 3.body 4.div

1.3 DOM事件流

DOM事件流分為三個階段:事件捕獲、目標(biāo)階段、事件冒泡。


2.事件處理程序

事件是用戶或者瀏覽器自身執(zhí)行的動作。響應(yīng)某個事件的函數(shù)叫做事件處理程序。

2.1 HTML事件處理程序

通過html的方式實現(xiàn)一個onclick事件

<input type = "button" onclick = "alert("hellp")">
2.2 DOM0級事件處理程序

這也是現(xiàn)在最常用的一種方法。為啥常用?原因一是簡單,原因二具有跨瀏覽器優(yōu)勢。

var btn = document.getElementById("myBtn");
btn.onclick = function () {
    alert("hello");
};
2.3 DOM2級事件處理程序

“DOM2級事件”定義了兩個方法,用于處理指定和刪除事件處理程序的操作:addEventListener()和removeEventListener()。
所有的DOM節(jié)點都包含這兩個方法。接收三個參數(shù):要處理的時間名、作為事件處理程序的函數(shù)和布爾值。最后這個布爾值是true,表示在捕獲節(jié)點調(diào)用時間處理程序;如果是false,表示在冒泡階段調(diào)用時間處理程序。

var btn = document.getElementById("myBtn");
btn.addEventListener("click", function(){
    alert(this.id);
}, false);

btn.addEventListener("click", function(){
    alert("Hello world!");
}, false);
2.4 IE事件處理程序

IE實現(xiàn)了DOM中類似的兩個方法:attachEvent()和detachEvent()。這兩個方法接收相同的兩個參數(shù):事件處理程序名稱與時間處理程序函數(shù)。IE8及更早的版本只支持事件冒泡,所以通過attachEvent()添加的時間處理程序都會被添加到冒泡階段。

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(){
    alert("Clicked");
});
btn.attachEvent("onclick", function(){
    alert("Hello world!");
});
2.5 跨瀏覽器的事件處理程序

要保證處理事件的帶啊能在大多數(shù)瀏覽器下一致的執(zhí)行,只需要關(guān)注冒泡階段。
第一個要創(chuàng)建的放大是addHandler(),它的作用是視情況而定分別使用DOM0級方法、DOM2級方法或IE方法來添加事件。addHandle()接受三個參數(shù):要操作的元素、事件名稱和事件處理程序函數(shù)。

var EventUtil = {
    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;
} }
};

3.事件對象

在觸發(fā)DOM上的某個事件時,會產(chǎn)生一個event對象,這個對象中包含素有時間有關(guān)的信息。事件的元素、事件的類型及其他相關(guān)信息。例如,鼠標(biāo)點擊導(dǎo)致的事件,可以獲取到鼠標(biāo)點擊的位置;鍵盤操作導(dǎo)致的事件,會包含與按下的鍵有關(guān)的信息。

3.1 DOM中的時間對象

兼容DOM的瀏覽器會將一個event對象傳入到時間處理程序中。無論指定時間處理程序時使用什么方法,都會傳入event對象。

var btn = document.getElementById("myBtn");
btn.onclick = function(event){ 
    alert(event.type);          //"click"
};

btn.addEventListener("click", function(event){
    alert(event.type);          //"click"
}, false);

關(guān)于Event對象包含的屬性與方法

屬性/方法 類型 讀/寫 說明
bubbles boolean 只讀 表明時間是否冒泡
cancelable boolean 只讀 表名是否可以取消事件默認(rèn)行為
currentTarget Element 只讀 其事件處理程序當(dāng)前正在處理事件的那個元素
defaultPrevented boolean 只讀 為true表示已經(jīng)調(diào)用了preventDefault()
detail Integer 只讀 與事件相關(guān)的細(xì)節(jié)信息
eventPhase Integer 只讀 調(diào)用時間處理程序的階段,1表示捕獲階段,2表示處于目標(biāo),3表示冒泡階段
preventDefault() Function 只讀 取消事件默認(rèn)行為
stopImmediatePropagation() Function 只讀 取消事件的進(jìn)一步捕獲或冒泡,同時阻止任何事件處理程序被調(diào)用
stopPropagation() Function 只讀 取消事件的進(jìn)一步捕獲或冒泡,如果bubbles為true,則可以使用這個方法
target Element 只讀 事件的目標(biāo)
trusted boolean 只讀 為true表示事件是瀏覽器生成。false表示事件使用開發(fā)人員通過JS創(chuàng)建
type String 只讀 被觸發(fā)事件的類型
view AbstractView 只讀 與事件關(guān)聯(lián)的抽象視圖。等同于發(fā)生事件的window對象

在對象處理程序內(nèi)部,對象this扥估currentTarget的值。

var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
    alert(event.currentTarget === this);    //true
    alert(event.target === this);           //true
};

4.事件類型

事件類型分類:UI事件、焦點事件、鼠標(biāo)事件、滾輪事件、文本事件、鍵盤事件、合成事件、變動事件。

4.1 UI事件

1.load事件:JS中最常用的就是load事件。當(dāng)頁面加載后就會觸發(fā)window上的load事件。如何定義onload事件呢?可以看下demo

第一種,JS聲明
EventUtil.addHandler(window, "load", function(event){
   alert("Loaded"); 
});

第二種,標(biāo)簽屬性
<body onload="alert('Loaded!')">

2.unload事件:文檔被完全卸載后觸發(fā)。只要用戶從一個頁面切換到另一個頁面就會觸發(fā)unload。利用這個事件最多的情況是清除引用,避免內(nèi)存泄露。

第一種,JS聲明
EventUtil.addHandler(window, "unload", function(event){
        alert("Unloaded");
});

第二種,標(biāo)簽屬性
<body onunload="alert('Loaded!')">

3.resize事件:當(dāng)瀏覽器窗口被調(diào)整到一個新的高度或?qū)挾葧r,就會觸發(fā)resize事件。注意resize事件會頻繁被觸發(fā),所以在盡量不要書寫大量運算邏輯,會導(dǎo)致瀏覽器變慢。

第一種,JS聲明
EventUtil.addHandler(window, "resize", function(event){
        alert("Resized");
});

第二種,標(biāo)簽屬性
<body onresize="alert('Loaded!')">

4.scroll事件:當(dāng)用戶滾動帶滾動條的元素內(nèi)容時觸發(fā)。在window對象上發(fā)生的,表示頁面中響應(yīng)元素的變化。跟resize事件類似,scroll會頻發(fā)觸發(fā)。所以在盡量不要書寫大量運算邏輯,會導(dǎo)致瀏覽器變慢

EventUtil.addHandler(window, "scroll", function(event){
    if (document.compatMode == "CSS1Compat"){
        alert(document.documentElement.scrollTop);
    } else {
        alert(document.body.scrollTop);
    }
});
4.2 焦點事件(這里就不寫demo了,會對事件做一個詳細(xì)的分析)
  • blur:在元素市區(qū)焦點時觸發(fā)。這個事件不會冒泡(但是可以捕獲階段監(jiān)聽到)
  • focus:在元素獲得焦點時觸發(fā)。這個事件不會冒泡(但是可以捕獲階段監(jiān)聽到)
  • focusion:在元素獲得焦點時觸發(fā)。這個事件會冒泡
  • focusout:在元素失去焦點時觸發(fā)。這個事件會冒泡
4.3 滾動與滾輪事件
  • click:在用戶單擊主鼠標(biāo)按鈕或者回車鍵觸發(fā)
  • dblclick:在用戶雙擊主鼠標(biāo)按鈕時觸發(fā)
  • mousedown:在用戶按下任意鼠標(biāo)按鈕時觸發(fā)。
  • mouseenter:鼠標(biāo)光標(biāo)從元素外部首次移動到元素范圍內(nèi)觸發(fā)。(IE、Firefox 9+和Opera支持)
  • mouseleave:在位于元素上方的鼠標(biāo)光標(biāo)移動到元素范圍之外時候觸發(fā)。(IE、Firefox 9+和Opera支持)
  • mousemove:當(dāng)鼠標(biāo)指針在元素內(nèi)部移動時重復(fù)觸發(fā)。
  • mouseout:在鼠標(biāo)指針位于一個元素上方,然后用戶將其移入另一個元素時觸發(fā)。
  • mouseover:在鼠標(biāo)指針位于一個元素外部,然后用戶將其移入另一個元素邊界之內(nèi)時觸發(fā)。
  • mouseup:在用戶釋放鼠標(biāo)按鈕時觸發(fā)。

1.客戶區(qū)坐標(biāo)位置(整個瀏覽器去掉工具欄等其他輔助工具的位置)

var div = document.getElementById("MyDiv");
EventUtil.addHandler(div, "click", function(event){
    event = EventUtil.getEvent(event);
    alert("Client coordinates: " + event.clientX + "," + event.clientY);
});

2.頁面坐標(biāo)位置

var div = document.getElementById("MyDiv");
EventUtil.addHandler(div, "click", function(event){
    event = EventUtil.getEvent(event);
    alert("Page coordinates: " + event.pageX + "," + event.pageY);
});

3.屏幕坐標(biāo)位置(獲取的是整個用戶操作系統(tǒng)界面的坐標(biāo))

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click", function(event){
    event = EventUtil.getEvent(event);
    alert("Screen coordinates: " + event.screenX + "," + event.screenY);
});

4.修改鍵
修改鍵就是Shift、Ctrl、Alt,這些經(jīng)常被用來修改鼠標(biāo)性情。因此DOM規(guī)定了四個屬性,來修改這些按鍵的狀態(tài):shiftKey、ctrlKey、altKey和metaKey。這些屬性都是布爾值,如果這些按鍵按下了則為true,否則為false。

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click", function(event){
    event = EventUtil.getEvent(event);
    var keys = new Array();
    if (event.shiftKey){
        keys.push("shift");
}
    if (event.ctrlKey){
        keys.push("ctrl");
}
    if (event.altKey){
        keys.push("alt");
}
    if (event.metaKey){
        keys.push("meta");
}
    alert("Keys: " + keys.join(","));
});
4.4 鍵盤與文本事件
  • keydown:當(dāng)用戶按下鍵盤上任意鍵時觸發(fā)。按住不放,重復(fù)執(zhí)行此事件
  • keypress:當(dāng)用戶按下鍵盤上的字符鍵時觸發(fā)。按住不放,重復(fù)執(zhí)行此事件
  • keyup:當(dāng)用戶釋放按鍵時觸發(fā)

1.鍵碼
鍵盤上每個按鍵都有一個keyCode屬性用于標(biāo)識按鍵的。

var textbox = document.getElementById("myText");
EventUtil.addHandler(textbox, "keyup", function(event){
    event = EventUtil.getEvent(event);
    alert(event.keyCode);
}); 

2.字符編碼
瀏覽器event對象都支持一個charCode屬性,這個屬性只有在發(fā)生keypress事件才有值,而且這個值是安縣哪個鍵鎖代表的字符的ASCII編碼。通常用來檢驗瀏覽器字符集。

3.textInput事件
用戶在可編輯區(qū)域中輸入字符時,就會觸發(fā)這個事件。

var textbox = document.getElementById("myText");
EventUtil.addHandler(textbox, "textInput", function(event){ event = EventUtil.getEvent(event);
alert(event.data);
}); 

5.內(nèi)存與性能

5.1 事件委托

對事件處理程序過多的時候,就可以通過委托的方式去解決。事件委托利用了事件冒泡。指定一個事件處理程序,就可以管理一類型所有的事件。

<ul id="myLinks">
    <li id="goSomewhere">Go somewhere</li>
    <li id="doSomething">Do something</li>
    <li id="sayHi">Say hi</li>
</ul>


function getEvent(){
    var list = document.getElementById("myLinks");
    EventUtil.addHandler(list, "click", function(event){
        event = EventUtil.getEvent(event);
        var target = EventUtil.getTarget(event);
    }
}

5.2 移除事件處理程序

每當(dāng)事件處理程序指定元素時,運行中的瀏覽器代碼與支持頁面交互的JS代碼會建立一個鏈接。這種鏈接越多,頁面執(zhí)行越慢??梢詢煞N方式規(guī)避這個問題,可以采用事件委托技術(shù)限制建立連接數(shù)。另外,在不需要的時候移除事件處理程序。

btn.onclick = funciotn(){
    //執(zhí)行某些操作
    btn.onclick = null; //移除事件處理程序
    document.getElementById("myDiv").innerHTML = "Processing...";
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??JavaScript 與 HTML 之間的交互是通過事件實現(xiàn)的。 ??事件,就是文檔或瀏覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,691評論 1 11
  • JavaScript 與 HTML 之間的交互是通過事件實現(xiàn)的。事件,就是文檔或瀏覽器窗口中發(fā)生的一些特定的交互瞬...
    threetowns閱讀 413評論 0 0
  • 事件處理程序在應(yīng)用中是必不可少的,雖然現(xiàn)在很多框架都有自己實現(xiàn)事件處理方法,但是熟知原生才能讓我們應(yīng)對各種各樣的需...
    俗三瘋閱讀 365評論 0 1
  • 事件類型 Web 瀏覽器中可能發(fā)生的事件有很多類型UI事件:當(dāng)用戶與界面上的元素交互時觸發(fā)。焦點事件:當(dāng)元素獲得或...
    shanruopeng閱讀 1,008評論 0 0
  • 事件流 事件流描述的是從頁面中接受事件的順序。但是IE和Netscape開發(fā)團隊提出了差不多相反的事件流的概念。I...
    losspm閱讀 311評論 0 0

友情鏈接更多精彩內(nèi)容