JavaScript學習總結(九)事件詳解
其實這篇文章挺早之前就寫了,但是由於sf儲存方面的bug,所以當時寫了一大堆,結果沒儲存,覺得這個沒寫完是個不小的遺憾,今天正好有空,就給補充下了,也正好給我的javascript
學習總結做一個完結篇。
其實之前的文章也涉及到部分事件,可以參照我的文章:JavaScript學習總結(三)BOM和DOM詳解
JavaScript學習系列文章目錄
- JavaScript學習總結(一)基礎部分
- JavaScript學習總結(二)陣列和物件部分
- JavaScript學習總結(三)BOM和DOM詳解
- JavaScript學習總結(四)function函式部分
- JavaScript學習總結(五)原型和原型鏈詳解
- JavaScript學習總結(六)資料型別和JSON格式
- JavaScript學習總結(七)Ajax和Http狀態字
- JavaScript學習總結(八)正規表示式
- JavaScript學習總結(九)事件詳解
這裡,主要討論一下js相關的事件——
事件處理程式
在DOM
中定義了一些事件, 而響應某個事件的函式就叫事件處理程式(或事件偵聽器)。事件處理程式的名字一般以“on”開頭,例如:onclick
等
事件冒泡與捕獲
事件流指的是頁面中接收事件的順序,IE
,火狐和chrome
瀏覽器都是事件冒泡,所謂是事件冒泡指的是事件最開始由最具體的元素接收,然後逐級向上傳播到不具體的節點。而事件捕獲則正好相反,事件捕獲是由Netscape
提出的,事件冒泡和捕獲具體如下圖所示:
雖然事件捕獲是Netscape唯一支援的事件流模型,但目前IE9,火狐和谷歌也都支援這種事件流模型。
事件冒泡的好處
因為事件具有冒泡機制,因此我們可以利用冒泡的原理,把事件加到父級上,觸發執行效果。這樣做的好處當然就是提高效能了,
<head lang="en"> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> window.onload = function () { var aUl = document.getElementsById("bubble"); var aLi = aUl.getElementsByTagName("li"); for(var i = 0;i<aLi.length;i++){ aLi[i].onmouseover = function () { this.style.backgroundColor = "blue"; }; ali[i].onmouseout = function () { this.style.backgroundColor = ""; } } }; </script> </head> <body> <div> <ul id = "bubble"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> </div> </body>
這樣我們就可以做到li上面新增滑鼠事件。但是如果說我們可能有很多個li
用for
迴圈的話就比較影響效能。
下面我們可以用事件委託
的方式來實現這樣的效果。html
不變:
<script type="text/javascript"> window.onload = function () { var aUl = document.getElementsById("bubble"); var aLi = aUl.getElementsByTagName("li"); //不管在哪個事件中,只要你操作的那個元素就是事件源。 // ie:window.event.srcElement // 標準下:event.target aUl.onmouseover = function (ev) { var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == "li"){ target.style.background = "blue"; } }; aUl.onmouseout = function (ev) { var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() = "li"){ target.style.background = ""; } } }; </script>
那麼,如何阻止事件的冒泡呢,看下面一個例子:
<div onclick="showMsg(this,event)" id="outSide" style="width:100px; height:100px; background:#000; padding:50px"> <div onclick="showMsg(this,event)" id="inSide" style="width:100px; height:100px; background:#CCC"></div> </div> <script type="text/javascript"> //阻止事件冒泡後,你點選灰色盒子,整個過程只彈一次對話方塊了(注意與預設情況對比) function showMsg(obj,e) { alert(obj.id); stopBubble(e) } //阻止事件冒泡函式 function stopBubble(e) { if (e && e.stopPropagation) e.stopPropagation() else window.event.cancelBubble=true } </script>
點選黑色外圍的效果圖:
DOM 0級事件處理程式
通過js
指定事件處理程式通常是將回撥函式賦給這個事件處理程式的屬性。每個元素都有自己的事件處理程式屬性(屬性小寫,例如:onclick
)
btn.onclick = function(){ console.log('hello'); };
使用DOM 0級指定的事件處理程式被認為是元素的方法。因此,this指向當前元素:
var btn = document.getElementById('myDiv'); //DOM上觸發的事件會產生一個事件物件event btn.onclick = function (event) { alert(this.id);//myDiv };
DOM level 1
DOM level 1
專注於 HTML
和 XML
文件模型。它含有文件導航和處理功能。
DOM level 1
於 1998 年 10 月 1 日成為 W3C 推薦標準。
第二版的工作草案在 2000 年 9 月 29 日。
值得一提的是:DOM level 0
並不是 W3C 規範。而僅僅是對在 Netscape Navigator 3.0
和 IE 3.0
中的等價功能性的一種定義。
DOM 2級事件處理程式
DOM 2
級定義了兩個方法,用於指定和刪除事件處理程式的操作:addEventListener()
和removeEventListener()
,他們都接受三個引數:
1.事件名。比如上面的click 2.作為事件處理程式的函式。 3.布林值(true表示捕獲階段呼叫事件處理程式,false表示冒泡階段)
通過Element
物件的addEventListener
方法,也可以定義事件的回撥函式。
//element.addEventListener(event, function, useCapture) var btn = document.getElementById('myDiv'); btn.addEventListener('click', function () { console.log(this.id); },false);
IE中的事件處理程式
IE9之前的IE瀏覽器不支援addEventListener()
和removeEventListener()
。
與其他瀏覽器不同的是,IE使用的是attachEvent()
和detachEvent()
方法來為DOM
新增事件處理程式,由於IE8
及更早版本只支援事件冒泡,所以他們只接受兩個引數:
1、事件處理程式名稱(前面要加on) 2、事件處理程式函式
使用attachEvent()
新增的事件處理程式如下:
var btn = document.getElementById('myDiv'); btn.attachEvent('onclick', function () { console.log(this.id); });
值得注意的是,使用attachEvent()
方法的情況下,事件處理程式會在全域性作用域中執行,所以,此時this
等於window
事件物件
在觸發DOM
上的某個事件時,會產生一個事件物件event
,這個物件包含著所有與事件相關的資訊。包括導致事件的元素、事件的型別以及其他與特定事件相關的資訊。event
物件會被作為第一個引數
傳遞給事件監聽的回撥函式。我們可以通過這個event
物件來獲取到大量當前事件相關的資訊:
type (String) — 事件的名稱 target (node) — 事件起源的DOM節點 currentTarget?(node) — 當前回撥函式被觸發的DOM節點(後面會做比較詳細的介紹) bubbles (boolean) — 指明這個事件是否是一個冒泡事件(接下來會做解釋) preventDefault(function) — 這個方法將阻止瀏覽器中使用者代理對當前事件的相關預設行為被觸發。比如阻止<a>元素的click事件載入一個新的頁面 cancelable (boolean) — 這個變數指明這個事件的預設行為是否可以通過呼叫event.preventDefault來阻止。 stopPropagation (function) — 取消事件的進一步捕獲或冒泡,bubbles為true使用這個方法 eventPhase:返回一個數字,表示事件目前所處的階段,0為事件開始從DOM表層向目標元素傳播,1為捕獲階段,2為事件到達目標元素,3為冒泡階段。
此外,事件物件還可能擁有很多其他的屬性,但是他們都是針對特定的event
的。比如,滑鼠事件包含clientX
和clientY
屬性來表明滑鼠在當前視窗的位置。
另外,stopPropagation()
方法用於立即停止事件在DOM中的傳播,即取消進一步的事件冒泡或捕獲。
var btn = document.getElementById('myDiv'); btn.onclick = function (event) { alert("clicked"); event.stopPropagation(); }; //避免觸發在document.body上的事件處理程式 document.body.onclick = function (event) { alert("Body clicked"); };
只有在事件處理程式執行期間,event
物件才會存在,一旦事件處理程式執行完畢,event
物件就會自動銷燬。
IE中的事件物件
在DOM 0
級中新增事件處理程式時,event
物件是作為window
物件的一個屬性存在的:
var btn = document.getElementById('myDiv'); btn.onclick = function (event) { var event = window.event; alert(event.type);//click };
IE 的event
物件同樣也包含與建立它的事件相關的屬性和方法。
cancleBubble 布林 預設值時false,但可以被設定成true來取消事件冒泡,與dom中的 stopPropagation()方法相同。 returnValue 布林 預設值是true,當設定成false時用以取消事件的預設行為 與dom中的preventDefault()相同。 srcElement 元素 事件的目標,與dom中的target屬性相同。 type 字串 被觸發的事件型別。
click事件
當使用者點選以後,event
物件會包含以下屬性。
pageX,pageY:點選位置相對於html元素的座標,單位為畫素。 clientX,clientY:點選位置相對於視口(viewport)的座標,單位為畫素。 screenX,screenY:點選位置相對於裝置顯示螢幕的座標,單位為裝置硬體的畫素
clientX,clientY
圖示:clientX
和clientY
,他們的值表示事件發生時滑鼠指標在視口中的水平和垂直座標(不包含滾動條區域)
偏移量
通過以下4個屬性可以取得元素的偏移量。 (1)offsetHeight:元素在垂直方向上佔用的空間大小,以畫素計。包括元素的高度、(可見的)水平滾動條的高度、上邊框高度和下邊框高度。 (2)offsetWidth:元素在水平方向上佔用的空間大小,以畫素計。包括元素的寬度、(可見的)垂直滾動條的寬度、左邊框寬度和右邊框寬度。 (3)offsetLeft:元素的左外邊框至包含元素的左內邊框之間的畫素距離。 (4)offsetTop:元素的上外邊框至包含元素的上內邊框之間的畫素距離。
pageX,pageY
這兩個屬性表示滑鼠游標在頁面中的位置,在頁面沒有滾動的情況下,pageX
,pageY
的值與clientX
,clientY
的值相等
滾動大小
滾動大小,指的是包含滾動內容的元素的大小。
以下是4個與滾動大小相關的屬性。 (1)scrollHeight:在沒有滾動條的情況下,元素內容的總高度。 (2)scrollWidth:在沒有滾動條的情況下,元素內容的總寬度。 (3)scrollLeft:被隱藏在內容區域左側的畫素數。通過設定這個屬性可以改變元素的滾動位置。 (4)scrollTop:被隱藏在內容區域上方的畫素數。通過設定這個屬性可以改變元素的滾動位置。
焦點事件
焦點事件會在頁面元素獲得或失去焦點時觸發,有以下4個焦點事件:
- blur:元素失去焦點時觸發,該事件不冒泡
- focus:元素獲得焦點時觸發。不冒泡
- focusin:元素獲得焦點時觸發,冒泡
- focusout:元素失去焦點時觸發,冒泡
滑鼠事件
DOM 3級定義了9個滑鼠事件:
click:當使用者點選滑鼠主鍵通常是指滑鼠左鍵或按Enter鍵時觸發。 dbclick:使用者雙擊滑鼠時觸發 mousedown:當使用者按下滑鼠任意一個鍵都會觸發,這個事件是不能夠通過鍵盤觸發的。 mousemove:當滑鼠在某元素周圍移動時重複觸發,該事件不能通過鍵盤事件觸發。 mouseout:當滑鼠離開元素時觸發,這個事件不能通過鍵盤觸發。 mouseover:當滑鼠進入元素時觸發,這個事件不能夠通過鍵盤觸發。 mouseenter:類似“mouseover”,但不冒泡,而且當游標移到後代元素上不會觸發。 mouseleave:類似“mouseout”,但不冒泡。在元素上方是不觸發。 mouseup:當使用者釋放滑鼠按鍵時觸發,不能夠通過鍵盤觸發。 傳遞給滑鼠事件處理程式的事件物件有clientX和clientY屬性,它們指定了滑鼠指標相對於包含視窗的座標。加入視窗的滾動偏移量,就可以把滑鼠位置轉換成文件座標。
頁面上的所有元素都支援滑鼠事件。除了mouseenter
和mouseleave
外,所有的事件都冒泡,並且他們的預設行為是可以被取消掉的。但取消滑鼠事件的預設行為可能會影響到其他事件,因為有些滑鼠事件是相互依賴的。
mouseenter和mouseover的不同: http://www.w3school.com.cn/tiy/t.asp?f=jquery_event_mouseenter_mouseover
拖拉事件
(1)drag
事件
drag事件在源物件被拖拉過程中觸發。
(2)dragstart
,dragend
事件
dragstart事件在使用者開始用滑鼠拖拉某個物件時觸發,dragend事件在結束拖拉時觸發。
(3)dragenter
,dragleave
事件
dragenter事件在源物件拖拉進目標物件後,在目標物件上觸發。dragleave事件在源物件離開目標物件後,在目標物件上觸發。
(4)dragover
事件
dragover事件在源物件拖拉過另一個物件上方時,在後者上觸發。
(5)drop
事件
當源物件被拖拉到目標物件上方,使用者鬆開滑鼠時,在目標物件上觸發drop事件。
相關文章
- 第九周學習總結
- JavaScript事件詳解JavaScript事件
- JavaScript keydown事件總結JavaScript事件
- 最全總結 JavaScript Array 方法詳解JavaScript
- Javascript Promise學習過程總結JavaScriptPromise
- JavaScript入門⑧-事件總結大全JavaScript事件
- Flutter學習總結系列----Flutter基礎全面詳解Flutter
- JavaScript學習筆記10: 事件繫結&監聽JavaScript筆記事件
- JavaScript 事件迴圈詳解(翻譯)JavaScript事件
- 【Javascript】DOM程式設計學習總結篇JavaScript程式設計
- 學習JavaScript非同步、事件迴圈JavaScript非同步事件
- JS學習之事件和事件繫結JS事件
- JavaWeb學習筆記_Day03_JavaScript詳解Web筆記JavaScript
- JavaScript學習小結JavaScript
- javascript ES5 物件導向的學習總結JavaScript物件
- 學習總結
- JavaScript 事件繫結JavaScript事件
- JavaScript --- Map集合結構詳解JavaScript
- JavaScript — Map集合結構詳解JavaScript
- 陪你一起學習之javascript事件JavaScript事件
- javaScript 習題總結(持續更新)JavaScript
- 九. Vuex詳解Vue
- ConstraintLayout 學習總結AI
- BOM學習總結
- tkinter學習總結
- vue學習總結Vue
- HSF學習總結
- ElasticSearch 學習總結Elasticsearch
- Storm學習總結ORM
- vue 學習總結Vue
- lua 學習總結
- Angularjs 學習總結AngularJS
- WebRTC學習總結Web
- GCD 學習總結GC
- CompletableFuture學習總結
- awk 學習總結
- MyBatis 學習總結MyBatis
- Maven學習總結Maven
- Ajax學習總結