成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

javascript----事件概述

wenzi / 1565人閱讀

摘要:作為事件處理程序的函數(shù)一個布爾值。最后這個布爾值為表示在捕獲階段調(diào)用事件處理程序,表示在冒泡階段調(diào)用事件處理程序。阻止特定事件的默認行為。

事件處理程序 DOM0級事件處理程序

通過Javascript指定事件處理程序的傳統(tǒng)方式,就是將一個函數(shù)賦值給一個事件處理程序?qū)傩浴?br>每個元素都有自己的事件處理程序?qū)傩?,這些屬性通常全部小寫,例如onclick。將這種屬性的值設(shè)置為一個函數(shù),就可以指定事件處理程序。

var btn = document.getElementById("myBtn");
// 添加事件處理程序
btn.onclick = function () {
    alert( this );//為DOM元素btn
};
// 移除事件處理程序
btn.onclick = null;

優(yōu)點:1.簡單2.具有跨瀏覽器的優(yōu)勢
缺點:在代碼運行之前不會指定事件處理程序,因此這些代碼在頁面中位于按鈕后面,就有可能在一段時間怎么點擊都沒反應(yīng),用戶體驗變差。

DOM2級事件處理程序

定義了兩個方法,用于處理指定和刪除事件處理程序的操作:addEventListener()和removeEventListener()。三個參數(shù),1.要處理的事件名。2.作為事件處理程序的函數(shù)3.一個布爾值。最后這個布爾值為true,表示在捕獲階段調(diào)用事件處理程序,false表示在冒泡階段調(diào)用事件處理程序。

// 添加多個事件處理程序
var btn = document.getElementById("myBtn");
btn.addEventListener("click",function (){
    alert( this );// 為DOM元素btn
},false );
btn.addEventListener("click",function () {
    alert("Hello World");
},false);

// 移除事件處理程序
btn.removeEventListener("click",function () {
    // 匿名函數(shù)無法被移除,移除失敗
},false);
   // 改寫
   var handler = function () {
    alert(this.id);
   };
   btn.addEventListener("click",handler,false);
   // 再次移除事件處理程序
   btn.removeEventListener("click",handler,false);// 移除成功

這兩個事件處理程序會按照添加他們的順序觸發(fā)。大多數(shù)情況,都是將事件處理程序添加到事件流的冒泡階段,這樣可以最大限度的兼容各種版本的瀏覽器。

優(yōu)點: 一個元素可以添加多個事件處理程序
缺點: IE8及以下瀏覽器不支持DOM2級事件處理程序。(包括IE8)

IE事件處理程序

定義了兩個方法,與上類似:attachEvent(),detachEvent()。這兩個方法接收相同的兩個參數(shù):事件處理程序名稱和事件處理程序函數(shù)。由于IE8以及更早版本的瀏覽器只支持事件冒泡,所以通過detachEvent()添加的事件處理程序會被添加到冒泡階段。

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(){
    alert( this );// window
});
btn.attachEvent("onclick", funciton(){
    alert("HELLO, WORLD");
});

點擊按鈕,這兩個事件處理程序的觸發(fā)順序與上述剛好相反。不是按照添加事件處理程序的順序觸發(fā),剛好相反。

優(yōu)點:一個元素可以添加多個事件處理程序
缺點:只支持IE。

跨瀏覽器的事件處理程序
var EventUtil = {
    addHandler : function ( ele, type, handler ) {
        if ( ele.addEventListener ) {
            ele.addEventListener( type, handler, false );
        } else if ( ele.attachEvent ) {
            ele.attachEvent( "on" + type, handler );
        } else {
            ele["on" + type] = handler
        }
    },
    removeHandler: function ( ele, type, handler ) {
        if ( ele.removeEventListener ) {
            ele.removeEventListener( type, handler, false );
        } else if ( ele.detachEvent ) {
            ele.detachEvent( "on" + type, handler );
        } else {
            ele[ "on" + type ] = null;
        }
    }
}
事件對象 DOM中的事件對象

兼容DOM的瀏覽器會將一個event對象傳入到事件處理程序中。無論指定事件處理程序時使用什么方法(DOM0級或DOM2)級,都會傳入event對象。event對象包含與創(chuàng)建它的特定事件有關(guān)的屬性和方法。觸發(fā)的事件類型不一樣,可用的屬性和方法也不一樣。不過,所有事件都有下表列出的成員

| 屬性/方法 | 類型 | 說明
| ---------—--- | ------------- | ------------
| bubbles
| cancebles
| currentTarget
| defaultPrevented
| detail
| evnetPhase
| preventDefault
| stopImmediatePropagation()
| stopPropagation()
| target
| trusted
| type
| view

1.currentTarget與target

target :事件的目標對象
currenTarget : 其當(dāng)前事件處理程序正在處理事件的那個元素

var btn = document.getElementById("myBtn");

btn.onclick = function ( e ) {
    console.log( this === e.currentTarget );// true
    console.log( this === e.target );// true
};

document.body.onclick = function ( e ) {
    console.log( this === e.currentTarget );// true
    console.log( this === e.target );// false
};

點擊按鈕,結(jié)果如上。

2.preventDefault()與cancelable

cancelable :只讀屬性,表明是否可以取消事件的默認行為,值為true便可以,反之不行。
preventDefault :阻止特定事件的默認行為。例如,鏈接的默認行為就是在被單擊時會導(dǎo)航到其href特性指定的URL。

var link = document.getElementById( "myLink" );
link.onclick = function ( e ) {
    // 阻止默認行為
    e.preventDefault();// 只有cancelable設(shè)置為true的事件,才可以使用
}

3.stopPropagation()與eventPhase

stopPropagation() : 取消事件進一步捕獲或冒泡,如果bubbles為true,則可以使用這個方法
eventPhase : 調(diào)用事件處理程序的階段:1.表示捕獲階段2.表示"處于目標階段"3.表示冒泡階段。

var btn = document.getElementById("myBtn");

document.body.addEventListener( "click", function ( e ) {
    alert( e.eventPhase );
}, true );// 1

btn.addEventListener( "click",function ( e ) {
    alert( e.eventPhase );
}, false );// 2

document.body.addEventListener( "click", function ( e ) {
    alert( e.eventPhase );
}, false );// 3

點擊btn按鈕彈出1,2,3。

var btn = document.getElementById("myBtn");

document.body.addEventListener( "click", function ( e ) {
    alert( e.eventPhase );// 1
}, true );

btn.addEventListener( "click",function ( e ) {
    // 阻止進一步的事件冒泡
    e.stopPropagation();
    alert( e.eventPhase );// 2
}, false );

document.body.addEventListener( "click", function ( e ) {
    alert( e.eventPhase );// 點擊按鈕時,事件處理程序被阻止,無反應(yīng)
}, false );

點擊btn按鈕彈出1,2。

var btn = document.getElementById("myBtn");

document.body.addEventListener( "click", function ( e ) {
    // 阻止進一步的事件冒泡
    e.stopPropagation();
    alert( e.eventPhase );// 1
}, true );

btn.addEventListener( "click",function ( e ) {
    alert( e.eventPhase );// 點擊按鈕時,事件處理程序被阻止,無反應(yīng)
}, false ); 

document.body.addEventListener( "click", function ( e ) {
    alert( e.eventPhase );// 點擊按鈕時,事件處理程序被阻止,無反應(yīng)
}, false );

點擊btn按鈕彈出1。

IE中的事件對象

訪問IE中的event對象有幾種不同的方式,取決于指定事件處理程序的方法。IE的event對象同樣也包含與創(chuàng)建它的事件相關(guān)的屬性和方法。與DOM中的event對象一樣,這些屬性和方法也會因為事件類型的不同而不同,但所有事件對象都會包含下表所列的屬性和方法。

| 屬性/方法 | 類型 | 說明
| ---------—--- | ------------- | ------------
| cancelBubble
| returnValue
| srcElement
| type

1.srcElement

事件的目標(與DOM中的target屬性相同)

var btn = document.getElementById("myBtn");

btn.onclick = function () {
    alert( window.event.srcElement === this )// true
};
btn.attachEvent("onclick", function (e) {
    alert( e.srcElement === this ) // false, IE事件處理程序綁定this的值為window
});

2.returnValue

默認值為true,但將其設(shè)置為false就可以取消事件的默認行為(與DOM中的preventDefault()作用相同)

var link = document.getElementById( "myLink" );
link.onclick = function () {
    // 阻止默認行為
    window.event.returnValue = false;
}

與DOM不同的是,在此沒有辦法確定事件是否能被取消。

3.cancelBubble

默認值為false,但將其設(shè)置為true就可以取消事件冒泡(與DOM中的stopPropagation()作用相同)

var btn = document.getElementById("myBtn");

btn.onclick = function () {
    alert( "Clicked" );
    window.event.cancelBubble = true;
};

document.body.onclick = function () {
    alert( "Body Clicked" )
};
跨瀏覽器的事件對象

要訪問IE中event對象有幾種不同的方式,取決于指定事件處理程序的方法。在使用DOM0級方法添加事件處理程序時,event對象作為window對象的一個屬性存在。使用IE事件處理程序,event對象可以通過window對象進行訪問,同時也會被當(dāng)做參數(shù)傳遞。

var EventUtil = {
    
    getEvent: function( event ){
        return event ? event : window.event
    }
}
事件類型

DOM3級事件模塊在DOM2級事件模塊基礎(chǔ)上重新定義了這些事件,也添加了一些新事件。包括IE9在內(nèi)的所有主流瀏覽器都支持DOM2級事件。IE9也支持DOM3級事件。

HTML5事件

DOMContentLoaded :

可以為document和window添加相應(yīng)的事件處理程序(盡管這個事件會冒泡到window,但它的目標實際上是document)。

DOMContentLoaded中的event對象不會提供額外的信息(其target屬性是document)
兼容性:IE9+,Fifrefox,Chrome,Safari3.1+,Opera9+。

hashchange :

必須要把hashchange事件處理程添加給window對象,然后URL參數(shù)列表只要變化就會調(diào)用它。

此時的event對象應(yīng)該額外包含兩個屬性:oldURL和newURL。這兩個屬性分別保存著參數(shù)列表變化前后的完整URL。
兼容性:IE8+,firefox3.6+,Safari5+,Chrome,Opera10.6+。在這些瀏覽器中只有Firefox6+,chrome和Opera支持oldURL和newURL屬性。為此,最好是使用location對象來確定當(dāng)前的參數(shù)列表。

鍵盤事件

keydown(任意鍵),keypress(字符鍵), keyup

發(fā)生keypress事件意味著按下的鍵會影響到屏幕中文本的顯示。在所有瀏覽器中,按下能夠插入或者刪除字符的鍵都會觸發(fā)keypress事件。

所有元素都支持以上三個事件,但只有在用戶通過文本框輸入文本時才最常用到

觸發(fā)順序:在用戶按下了一個字符鍵時,keydown-->keypress-->keyup。在用戶按下的是一個非字符鍵,keydown-->keyup。

event對象

shiftKey,ctrlKey,altKey和metaKey屬性。

在發(fā)生keydown和keyup事件時,event對象的keyCode屬性會包含一個鍵碼。

兼容性:IE不支持metaKey
Working With the Keyboard

鼠標事件

mousedown,mouseup

click,dbclick

所有元素都支持鼠標事件。

觸發(fā)順序:mousedown-->mouseup-->click-->mousedown-->mouseup-->click--dbclick。在IE8以及之前版本,有一個小bug,會跳過第二個mousedown和click

event對象:

clientX和clientY:表示事件發(fā)生時,鼠標指針在視口中的水平和垂直坐標

PageX和PageY:表示鼠標光標在頁面中的位置,因此坐標是從頁面本身,而非視口的左邊和頂邊計算的。

screenX和screenY:可以確定鼠標事件發(fā)生時,鼠標指針相對于整個屏幕的坐標信息。

shiftKey,ctrlKey,altKey和metaKey屬性。

mousedown和mouseup事件,還包括一個button屬性:表示按下或釋放的按鈕DOM的button屬性可能有如下3個值,0表示主鼠標按鈕,1表示中間的鼠標按鈕,2表示次鼠標按鈕。

兼容性:

IE8以及更早版本不支持事件對象上的頁面坐標,不過使用客戶區(qū)坐標和滾動信息可以計算出來。

IE8以及更早版本不支持metaKey屬性。

touchstart

內(nèi)存和性能 事件處理程序?qū)π阅艿挠绊?/b>

在javascript中,添加到頁面上的事件處理程序數(shù)量將直接關(guān)系到頁面的整體運行性能。

1.每個函數(shù)(事件處理程序)都是對象,都會占用內(nèi)存。內(nèi)存中的對象越多,性能就越差。
2.必須事先指定所有 事件處理程序而導(dǎo)致的DOM訪問次數(shù),會延遲整個頁面的交互就緒時間。
3.每當(dāng)將 事件處理程序指定給元素時,運行中的瀏覽器代碼與支持頁面交互的Javascript代碼之間就會建立一個連接。這種連接越多,頁面執(zhí)行起來越慢。

L
O
V
E
var l = document.getElementById( "love-l" ); var o = document.getElementById( "love-o" ); var v = document.getElementById( "love-v" ); var e = document.getElementById( "love-e" ); l.addEventListener("click", function () { alert(" L ") }, false); o.addEventListener("click", function () { alert( "O" ) }, false); v.addEventListener("click", function () { alert( "V" ) }, false); e.addEventListener("click", function () { alert( "E" ) }, false);

在上面的示例中,為每個元素的點擊事件都綁定了不同事件處理程序。

取得了4個DOM元素。==>DOM訪問次數(shù)為4次

添加了4個事件處里程序。==>內(nèi)存中的對象多增加了4個

相應(yīng)的事件處理程序與指定元素連接了4次==》連接數(shù)4

如果頁面復(fù)雜,那么就會有數(shù)不清的代碼用于添加事件處理程序。影響頁面性能。

事件委托

對事件處理程序過多問題的解決方案就是事件委托。

事件委托利用了事件冒泡,只指定一個事件處理程序,就可以管理 某一類型(例如:點擊事件)的所有事件。
如果可行的話,可以考慮為document對象添加一個事件處理程序,用以處理頁面上特定類型的事件。有點如下

document對象很快就可以訪問,而且可以在頁面生命周期中的任何時點上為它添加事件處理程序(無需等待load和DOMContentLoaded事件)。換句話說,只要可點擊的元素呈現(xiàn)在頁面上,就可以立即具備適當(dāng)?shù)墓δ?/p>

在頁面中設(shè)置事件處理程序所需的時間更少。只添加一個事件處理程序所需的DOM引用更少,所花的時間更少。 整個頁面所占得內(nèi)存空間更少

var love = document.getElementById( "love-wrapper" );
love.addEventListener("click", function ( e ) {
    switch ( e.target.id ) {
        case "love-l" : 
            alert("L");
            break;
        case "love-o" :
            alert("O");
            break;
        case "love-v" :
            alert("V");
            break;
        case "love-e" :
            alert("E");
            break;
    }
},false)

在上面的示例中

取得了1個DOM元素。==>DOM訪問次數(shù)減少到了1次

添加了1個事件處理程序。==>內(nèi)存中的對象只增加了1個

相應(yīng)的事件處理程序與指定元素連接了4次==>連接數(shù)1

實現(xiàn)了和上一個例子中一樣的效果。但是卻有效的控制了DOM訪問次數(shù),事件處理程序的添加個數(shù),以及DOM元素與相應(yīng)的事件處理程序的連接次數(shù)。

移除事件處理程序

利用事件委托我們可以有效的控制相應(yīng)的事件處理程序與指定元素的連接次數(shù)。另外,在不需要的時候移除事件處理程序,也是解決這個問題的一種方案。內(nèi)存中留有那些過時不用的"空事件處理程序,也是造成Web應(yīng)用程序內(nèi)存和性能問題的主要原因"。

有兩種情況可能導(dǎo)致上述問題

帶有事件處理程序的 指定元素 通過DOM操作被刪除了,頁面中的某一部分被替換了,導(dǎo)致帶有事件處理程序的 指定元素 被刪除了。

卸載頁面的時候。

第一種情況:本質(zhì)上來講都是一種情況,就是帶有事件處理程序的 指定元素被刪除了,但是其事件處理程序仍然和 指定元素保持著引用關(guān)系,導(dǎo)致其事件處理程序無法被當(dāng)做垃圾回收。(尤其是IE)會做出這種處理

var handler = function () { // 刪除指定元素 document.getElementById( "myDiv" ).removeChild(); } var btn = document.getElementById("myBtn"); btn.addEventListener("click", handler, false);

點擊按鈕時,按鈕被刪除,但是其事件處理程序卻還和其保持了引用關(guān)系,導(dǎo)致內(nèi)存增加。因此在知道 指定元素可能被刪除的情況下,先解除他們之間的引用關(guān)系。如下

var handler = function () { // 解除連接引用關(guān)系 btn.removeEventListener( "click", handler, false ); // 刪除指定元素 document.getElementById( "myDiv" ).removeChild(); } var btn = document.getElementById("myBtn"); btn.addEventListener("click", handler, false);

這樣通過解除引用連接關(guān)系,也可以提升頁面性能。

第二種情況:IE8及更早瀏覽器在這種情況下仍然是問題最多的瀏覽器。如果在頁面卸載之前,沒有清理干凈事件處理程序,那它們就會滯留在事件處理程序中。

一般來說,最好的做法是在頁面卸載之前,先通過unload事件處理程序移除所有事件處理程序。

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/78645.html

相關(guān)文章

  • Node.js 指南(阻塞與非阻塞概述

    摘要:標準庫中的所有方法都提供非阻塞的異步版本,并接受回調(diào)函數(shù),某些方法還具有對應(yīng)的阻塞方法,其名稱以結(jié)尾。比較代碼阻塞方法同步執(zhí)行,非阻塞方法異步執(zhí)行。 阻塞與非阻塞概述 此概述介紹了Node.js中阻塞與非阻塞調(diào)用之間的區(qū)別,此概述將引用事件循環(huán)和libuv,但不需要事先了解這些主題,假設(shè)讀者對JavaScript語言和Node.js回調(diào)模式有基本的了解。 I/O主要指與libuv支持的...

    zebrayoung 評論0 收藏0
  • [譯文] JavaScript工作原理:引擎、運行時、調(diào)用棧概述

    摘要:調(diào)用棧是單線程編程語言,意味著它只有單一的調(diào)用棧。調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),基本記錄了程序運行的位置。舉個例子,先來看如下所示的代碼當(dāng)引擎開始執(zhí)行這段代碼時,調(diào)用棧將是空的。這正是拋出異常時棧追蹤的構(gòu)造過程這基本上就是異常拋出時調(diào)用棧的狀態(tài)。 原文 How JavaScript works: an overview of the engine, the runtime, and the c...

    PAMPANG 評論0 收藏0
  • 【譯】JavaScript 如何工作:對引擎、運行時、調(diào)用堆棧的概述

    摘要:調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了我們在程序中的位置。當(dāng)從這個函數(shù)返回的時候,就會將這個函數(shù)從棧頂彈出,這就是調(diào)用棧做的事情。而且這不是唯一的問題,一旦你的瀏覽器開始處理調(diào)用棧中的眾多任務(wù),它可能會停止響應(yīng)相當(dāng)長一段時間。 原文地址: https://blog.sessionstack.com... PS: 好久沒寫東西了,最近一直在準備寫一個自己的博客,最后一些技術(shù)方向已經(jīng)敲定了,又可以...

    Warren 評論0 收藏0
  • JavaScript是如何工作的:引擎,運行時和調(diào)用堆棧的概述!

    摘要:調(diào)用棧是一種單線程編程語言,這意味著它只有一個調(diào)用堆棧。調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了我們在程序中的位置。而且這不是唯一的問題,一旦你的瀏覽器開始處理調(diào)用棧中的眾多任務(wù),它可能會停止響應(yīng)相當(dāng)長一段時間。 本文是旨在深入研究JavaScript及其實際工作原理的系列文章中的第一篇:我們認為通過了解JavaScript的構(gòu)建塊以及它們是如何工作的,將能夠編寫更好的代碼和應(yīng)用程序。我們還將分...

    PiscesYE 評論0 收藏0
  • JavaScript是如何工作的:引擎,運行時間以及回調(diào)的概述

    摘要:是如何工作的引擎,運行時以及調(diào)用棧的概述原文譯者隨著變得越來越流行,團隊在多個層級都對它進行利用前端,后端,混合應(yīng)用,嵌入式設(shè)備以及更多。這個將會在是如何工作的的第二部分進一步解釋。 How JavaScript works: an overview of the engine, the runtime, and the call stack JavaScript是如何工作的:引擎,運...

    he_xd 評論0 收藏0
  • JavaScript如何工作:引擎,運行時和調(diào)用堆棧的概述

    摘要:如果我們進入一個函數(shù),我們在堆棧的頂部??纯聪旅娴拇a當(dāng)引擎開始執(zhí)行此代碼時,調(diào)用堆棧將為空。之后,步驟如下調(diào)用堆棧中的每個條目稱為堆棧幀。這正是拋出異常時構(gòu)造堆棧跟蹤的方式當(dāng)異常發(fā)生時,它基本上是調(diào)用堆棧的狀態(tài)。 隨著JavaScript越來越受歡迎,團隊正在利用這個技術(shù)棧在多個層次- 前端,后端,混合應(yīng)用程序,嵌入式設(shè)備等等提供支持。 這篇文章旨在成為系列中第一個旨在深入挖掘Jav...

    wwolf 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<