亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

DOM中事件處理概覽與原理的全面解析

2019-11-20 09:13:59
字體:
來源:轉載
供稿:網友

事件是一種異步編程的實現方式,本質上是程序各個組成部分之間的通信,DOM支持大量的事件; 

本文通過這幾點向大家詳細解析事件處理的基本原理:事件類型、事件目標、事件處理程序、事件對象、事件傳播

最后再向大家介紹Event對象; 

一、事件類型(event type):是一個用來說明發生了什么類型事件的全小寫的字符串,如‘mouseover'
傳統事件類型:表單事件,Window事件,鼠標事件,鍵盤事件,DOM事件, HTML5事件,觸摸屏和移動設備事件等 

二、事件目標(event target):觸發事件的對象 

三、事件處理程序(或事件監聽程序)(event listener):處理或響應事件的函數。當某對象觸發某事件時,瀏覽器將自動調用在該對象上注冊的函數;
注冊事件處理程序(監聽事件):
1.作為HTML屬性注冊(只會在冒泡階段觸發)如<table id="t" onclick="modifyText();">;而某些事件類型通常直接在瀏覽器上觸發,而非任何特定文檔元素上觸發,把這些事件處理程序放在<body>標簽上,但瀏覽器會在Window對象上注冊它們,如<body onload="alert('Hello world!')">,這些事件有:
onafterprint onfocus ononline onresize onbeforeprint onhashchange 
onpagehide onstorage onbeforeunload onload onpageshow onundo 
onblur onmessage onpopstate onunload onerror onoffline onredo
作為HTML屬性的事件的值是JS代碼字符串,是處理函數的主體,不含{},注意:盡量不要在任何其他HTML標簽上注冊事件,它違反了HTML與JavaScript代碼相分離的原則,倘若事件函數可能還沒加載進來就點擊了事件對象元素,這會導致錯誤;

2.作為DOM元素的屬性來注冊(只會在冒泡階段觸發),此時的事件處理程序屬性的名字需加‘on'前綴,這種方式兼容所有瀏覽器,唯一的缺點是只能注冊一個事件處理函數,如果定義兩次onclick屬性,后一次定義會覆蓋前一次;如:window.onload = function(){...};

3.除了IE8及之前版本外的所有瀏覽器中,DOM的事件操作(監聽和觸發),都定義在EventTarget接口。Element節點、document節點和window對象,都部署了這個接口。此外,XMLHttpRequest、AudioNode、AudioContext等瀏覽器內置對象,也部署了這個接口。該接口有三個方法,addEventListener和removeEventListener用于綁定和移除監聽函數,dispatchEvent用于觸發事件;
addEventListener(type,listener,boolean)方法來注冊listener,第三個參數設置事件的傳播方式,通常使用默認值false,表示監聽函數只在冒泡階段(pupple)被觸發,當設為true時,表示監聽函數在捕獲階段(capture)觸發;可以為同一對象上的同一類型事件注冊任意多個listener,所有listener會按照注冊順序觸發(注冊重復的listener將會被瀏覽器忽略);
如果希望向監聽函數傳遞參數,可以用匿名函數包裝一下監聽函數,如elm.addEventListener('click',function(){listen('實參')},false);
當注冊的listener是一個對函數的引用變量,就可以用removeEventLestener(type,listener,boolean)在事件目標上刪除該listener,對同一監聽事件的冒泡事件和捕獲事件需要分別刪除,兩者互不干擾;

var div = document.getElementById('div');var listener = function (event) {            /* do something here */        }; div.addEventListener('click', listener, false); div.removeEventListener('click', listener, false);

dispatchEvent(event)方法在當前節點上手動觸發指定事件,從而觸發監聽函數的執行。該方法返回一個布爾值,只要有一個監聽函數調用了Event.preventDefault(),就返回false,否則為true,參數是一個Event對象的實例,該參數不能為空,且必須是一個有效的事件對象,否則報錯;
btn.addEventListener('click', listener, false);
     var e = new Event('click');
btn.dispatchEvent(e); //在btn上立即觸發click事件,將立即調用listener 

下面例子根據dispatchEvent方法的返回值,判斷事件是否被取消了
var canceled = !btn.dispatchEvent(event);
if (canceled) { console.log('事件取消'); } 
else { console.log('事件未取消'); }} 

4.IE8及之前版本僅支持attachEvent (type,listener)和detachEvent(type,listener),它們的用法和addEventListener的區別:a.參數只有兩個;b.參數type必須加'on'前綴;c.它允許對同一監聽事件進行重復注冊,且都會被調用;d.使用attachEvent方法有個缺點,是this的值會變成 window 對象而不是觸發事件的元素;
調用順序問題:1).通過設置對象屬性或HTML屬性注冊的處理程序一直優先調用;
                         2).使用addEventListener 注冊的處理程序按照它們的注冊順序調用;
                         3).舊版IE中使用attachEvent注冊的處理程序可能按照任何順序調用。
返回值問題:

1).事件處理程序的返回值只對通過屬性注冊的處理程序才有意義,通過設置對象屬性或HTML屬性注冊 事件處理程序的返回值為false,就是告訴瀏覽器不要執行這個事件相關的默認操作。當瀏覽器要跳轉到新頁面時觸發Window對象的onbeforeunload事件,若它的的返回值為字符串,則它將出現在詢問確認對話框中;

2).addEventListener()或attachEvent()注冊事件處理程序若要取消瀏覽器的默認操作必須調用preventDefault()方法或設置事件對象的returnValue屬性。
this指向問題:

1).addEventListener方法指定的監聽函數,內部的this對象總是指向觸發事件的那個節點;
2).IE8及以前的attachEvent方法注冊的事件處理函數的this指向全局對象;
以下寫法的this對象都指向Element節點。 
                    element.onclick = print;
                    element.addEventListener('click', print, false)
                    element.onclick = function () {console.log(this.id);}
                    <element onclick="console.log(this.id)">
 以下寫法的this對象,都指向全局對象。 
                    element.onclick = function (){ doSomething() }; 
                    element.setAttribute('onclick', 'doSomething()'); 
                    <element onclick="doSomething()"> 
                    element.attachEvent('onclick',doSomething) //IE8
內存問題:對如下代碼,每個循環中都會創建一個新的匿名函數,占用的內存越來越多;由于沒有保持到匿名函數的引用,它不可能被調用 removeEventListener;所以應當把第二參數listener保持為對處理事件函數的引用;                  

 for(i=0 ; i<els.length ; i++){   els[i].addEventListener("click", function(e){/*do something*/}, false});     }

通用的兼容舊版IE的工具函數:
確保事件處理程序的this指向事件的目標對象的工具函數addEvent

 function addEvent(target,type,func){   if(target.addEventListener){     target.addEventListener(type,func,false);   }else{     target.attachEvent('on'+type,function(e){  //這里attachEvent注冊的處理函數未綁定引用,所以無法用detachEvent刪除       return func.call(target,e);     });   } }

通用的事件處理程序(因為IE8及以前版本,作為事件目標的on-屬性的處理程序需要window.event來獲得事件對象,且觸發事件的目標節點對象通過event.srcElement屬性獲得) 

function func(event){   var event = event||window.event;   var target = event.target || event.srcElement;   //......處理程序代碼 }

四、事件傳播(event propagation):是瀏覽器決定哪個對象觸發其事件處理程序的過程。
“DOM2級事件”規定的事件流包括三個階段:事件捕獲階段==>處于目標階段==>事件冒泡階段。首先發生的是事件捕獲階段(從外層向內層傳播),為事件傳播經過的所有節點截獲事件提供了機會。然后是實際的目標接收事件(按注冊順序執行)。最后一個階段是冒泡階段(從內層向外層冒泡)。

當容器元素及嵌套元素,即在捕獲階段又在冒泡階段調用事件處理程序時:事件按DOM事件流的順序執行事件處理程序,且當事件處于目標階段時,事件調用順序決定于綁定事件的書寫順序

如果希望事件到某個節點為止,不再傳播,有兩種方式:

1.使用事件對象的event.stopPropagation()方法來阻止當前監聽函數的傳播;

2.使用事件對象的event.stopImmediatePropagation()方法來阻止當前事件在其事件對象上的所有監聽函數的傳播; 

事件的代理(delegation):由于事件會在冒泡階段向上傳播到父節點,因此可以把子節點的監聽函數定義在父節點上,由父節點的監聽函數統一處理多個子元素的事件;

五、事件對象(Event):事件發生以后,會生成一個事件對象,作為參數傳給監聽函數。瀏覽器原生提供一個Event對象,所有的事件都是這個對象的實例,或者說繼承了Event.prototype對象。Event對象本身就是一個構造函數,可以用來生成新的實例。 

var ev = new Event("look", {"bubbles":true, "cancelable":false});
document.dispatchEvent(ev);

Event構造函數接受兩個參數。第一個參數是字符串,表示事件的名稱;第二個參數是一個對象,表示事件對象的配置。該參數可以有以下兩個屬性。
bubbles:布爾值,可選,默認為false,表示事件對象是否冒泡。
cancelable:布爾值,可選,默認為false,表示事件是否可以被取消。 

Event對象的屬性:
1.與事件的階段有關: 
bubbles: 只讀屬性,返回一個布爾值,表示當前事件是否會冒泡,可根據事件是否會冒泡來調用不同的函數。 
eventPhase:返回一個整數值(0,1,2,3之一),表示事件目前所處的狀態
<0,事件目前沒有發生。
<1,事件目前處于捕獲階段,即處于從祖先節點向目標節點的傳播過程中。該過程是從Window對象到Document節點,再到HTMLHtmlElement節點,直到目標節點的父節點為止。
<2,事件到達目標節點,即target屬性指向的那個節點。
<3,事件處于冒泡階段,即處于從目標節點向祖先節點的反向傳播過程中。該過程是從父節點一直到Window對象。只有bubbles屬性為true時,這個階段才可能發生 

2.與事件的默認行為有關: 
cancelable:返回一個布爾值,表示事件是否可以取消。如果要取消某個事件,需要在這個事件上面調用preventDefault方法 
defaultPrevented:返回一個布爾值,表示該事件是否調用過preventDefault方法。

3.與事件的目標節點有關: 
currentTarget:返回事件執行的監聽函數所綁定的那個節點。 
target:返回觸發事件的那個節點。在IE6―IE8之中,該屬性的名字不是target,而是srcElement

4.與事件對象的其他信息相關: 
type:返回一個字符串,表示事件類型 
detail:返回一個數值,表示事件的某種信息。具體含義與事件類型有關,對于鼠標事件,表示鼠標按鍵在某個位置按下的次數,比如對于dblclick事件,detail屬性的值總是2 
timeStamp:返回一個毫秒時間戳,表示事件發生的時間。從PerformanceTiming.navigationStart開始計算,即表示距離用戶導航至該網頁的時間。如果想將這個值轉為Unix紀元時間戳,就要計算event.timeStamp + performance.timing.navigationStart
isTrusted:返回一個布爾值,表示該事件是否可以信任。用處不大,不同瀏覽器的支持不一樣。

Event對象的方法: 
preventDefault():取消瀏覽器對當前事件的默認行為,該方法生效的前提是,事件的cancelable屬性為true,如果為false,則調用該方法沒有任何效果。 
stopPropagation():終止事件在傳播過程的捕獲、目標處理或起泡階段進一步傳播。調用該方法后,該節點上處理該事件的處理程序將被調用,事件不再被分派到其他節點。注意:該方法不能阻止同一個 Document 節點上的其他事件句柄被調用,但是它可以阻止把事件分派到其他節點 
stopImmediatePropagation():阻止同一個事件的其他監聽函數被調用,只要其中有一個監聽函數調用了該方法,其他的監聽函數就不會再執行了。

參考鏈接: 
http://javascript.ruanyifeng.com/dom/event.html#toc31 
https://developer.mozilla.org/zh-CN/docs/Web/API 
JavaScript權威指南第六版

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线免费视频| 欧美精品在线网站| 欧美激情精品久久久久久大尺度| 欧美激情网友自拍| 色综合久久中文字幕综合网小说| 国产做受69高潮| 久久久免费高清电视剧观看| www.99久久热国产日韩欧美.com| 欧美一二三视频| 中文字幕在线观看日韩| 中文字幕久久精品| 97视频在线观看播放| 最新国产成人av网站网址麻豆| 国产精品福利在线观看| 在线视频中文亚洲| 欧美国产视频日韩| 亚洲一区二区中文字幕| 欧美激情在线播放| 国产精品吴梦梦| 久久精品这里热有精品| 亚洲国产欧美一区二区三区久久| 91福利视频网| 中文字幕在线观看亚洲| 欧美极品少妇全裸体| 日韩精品欧美激情| 日韩av最新在线观看| 91超碰caoporn97人人| 少妇av一区二区三区| 国产精品久久久av久久久| 亚洲国产第一页| 久久精品视频中文字幕| 久久婷婷国产麻豆91天堂| 久久久久久久久久亚洲| 亚洲人成在线播放| 91网站免费观看| 91精品国产综合久久男男| 日本免费久久高清视频| 性日韩欧美在线视频| 亚洲香蕉伊综合在人在线视看| 国产一区二区三区久久精品| 最新中文字幕亚洲| 欧美成人激情图片网| 成人精品在线视频| 亚洲一区二区三区乱码aⅴ蜜桃女| 在线成人免费网站| 亚洲国产成人久久综合一区| 亚洲激情电影中文字幕| 久久免费国产视频| 亚洲欧洲一区二区三区在线观看| 国产盗摄xxxx视频xxx69| 97av在线视频免费播放| 久热在线中文字幕色999舞| 国产成人在线亚洲欧美| 欧美孕妇与黑人孕交| 亚洲伊人第一页| 欧美黑人xxxx| 日韩欧美在线免费观看| 欧美精品999| 中文字幕日韩有码| 欧美大人香蕉在线| 久久久精品美女| 亚洲福利视频在线| 国产精品一区二区久久久久| 日韩av免费看网站| 国产精品亚洲第一区| 国产精品日韩在线一区| 伊人久久久久久久久久久久久| 欧美国产日本高清在线| 国产日韩在线免费| 这里只有精品在线观看| 色先锋资源久久综合5566| 午夜精品久久久99热福利| 国产婷婷成人久久av免费高清| 91精品中文在线| 亚洲黄在线观看| 久久这里只有精品视频首页| 免费99精品国产自在在线| 亚洲精品一区在线观看香蕉| 亚洲成av人影院在线观看| 日韩欧美一区二区在线| 91超碰中文字幕久久精品| 亚洲人成电影在线观看天堂色| 国产成人精品久久久| 成人久久久久久| 日韩成人在线网站| 亚洲直播在线一区| 在线视频欧美日韩| 57pao国产精品一区| 国产激情久久久久| 欧美成人精品在线| 欧美成人自拍视频| 日韩精品在线影院| 成人黄色片网站| 欧美噜噜久久久xxx| 日韩精品中文字幕在线播放| 亚洲免费视频在线观看| 久久中国妇女中文字幕| 日韩美女视频免费在线观看| 国产精品一区二区三区久久久| 日日噜噜噜夜夜爽亚洲精品| 欧美做爰性生交视频| 国产精品三级网站| 亚洲国产精品高清久久久| 日韩在线观看你懂的| 国产精品69精品一区二区三区| 久久色免费在线视频| 国产最新精品视频| 久久夜色精品亚洲噜噜国产mv| 欧美精品在线免费播放| 国产日韩在线亚洲字幕中文| 亚洲精品美女久久久| 81精品国产乱码久久久久久| 狠狠躁18三区二区一区| 国产一区二区在线免费| 日韩一区二区福利| 国产精品爽爽爽爽爽爽在线观看| 精品日韩美女的视频高清| 国产成人在线播放| 青草热久免费精品视频| 在线色欧美三级视频| 欧美情侣性视频| 一本久久综合亚洲鲁鲁| 懂色av一区二区三区| 国产精品久久综合av爱欲tv| 日韩中文字幕精品| 91系列在线观看| 欧美精品久久久久久久久久| 久久精品一偷一偷国产| 欧美日本黄视频| 国产欧美在线播放| 日韩亚洲一区二区| 九九热这里只有精品免费看| 日产精品99久久久久久| 狠狠操狠狠色综合网| 国产精品亚洲综合天堂夜夜| 亚洲国内高清视频| 欧美精品一区二区免费| 国产在线播放不卡| 精品久久久国产精品999| 91国产一区在线| 欧美一区视频在线| 国内精品久久久久久久久| 国产91在线播放九色快色| 久久亚洲精品网站| 91精品国产综合久久香蕉922| 亚洲国产精品一区二区久| 日韩美女福利视频| 欧美性感美女h网站在线观看免费| 美日韩精品视频免费看| 国产91成人video| 欧美一级黑人aaaaaaa做受| 精品久久久久久久久国产字幕| 日韩精品在线观看一区二区| 亚洲欧美国产一本综合首页| 亚洲一区二区久久| 国产精品大片wwwwww| 精品成人久久av| 欧美日韩一区二区精品| 91麻豆桃色免费看| 日韩免费在线视频| 精品女同一区二区三区在线播放| 欧美一级在线亚洲天堂| 九九视频直播综合网| 成人免费视频xnxx.com|