JavaScript每天必學之事件_javascript技巧

來源:互聯網
上載者:User

其實這篇文章挺早之前就寫了,但是由於sf儲存方面的bug,所以當時寫了一大堆,結果沒儲存,覺得這個沒寫完是個不小的遺憾,今天正好有空,就給補充下了,也正好給我的javascript學習總結做一個完結篇。 

這裡,主要討論一下js相關的事件—— 

事件處理常式 

在DOM中定義了一些事件, 而響應某個事件的函數就叫事件處理常式(或事件接聽程式)。事件處理常式的名字一般以“on”開頭,例如:onclick等 

事件冒泡與捕獲 

事件流指的是頁面中接收事件的順序,IE,Firefox和chrome瀏覽器都是事件冒泡,所謂是事件冒泡指的是事件最開始由最具體的元素接收,然後逐級向上傳播到不具體的節點。而事件捕獲則正好相反,事件捕獲是由Netscape提出的,事件冒泡和捕獲具體如下圖所示:

 

雖然事件捕獲是Netscape唯一支援的事件流模型,但目前IE9,Firefox和Google也都支援這種事件流模型。 

事件冒泡的好處 

因為事件具有冒泡機制,因此我們可以利用冒泡的原理,把事件加到父級上,觸發執行效果。這樣做的好處當然就是提高效能了,

 <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上觸發的事件會產生一個事件對象eventbtn.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個焦時間點事件:
 1.blur:元素失去焦點時觸發,該事件不冒泡
 2.focus:元素獲得焦點時觸發。不冒泡
 3.focusin:元素獲得焦點時觸發,冒泡
 4.focusout:元素失去焦點時觸發,冒泡 

滑鼠事件 

DOM 3級定義了9個滑鼠事件:
 click:當使用者點擊滑鼠主鍵通常是指滑鼠左鍵或按斷行符號鍵時觸發。

dbclick:使用者雙擊滑鼠時觸發

mousedown:當使用者按下滑鼠任意一個鍵都會觸發,這個事件是不能夠通過鍵盤觸發的。

mousemove:當滑鼠在某元素周圍移動時重複觸發,該事件不能通過鍵盤事件觸發。

mouseout:當滑鼠離開元素時觸發,這個事件不能通過鍵盤觸發。

mouseover:當滑鼠進入元素時觸發,這個事件不能夠通過鍵盤觸發。

 mouseenter:類似“mouseover”,但不冒泡,而且當游標移到後代元素上不會觸發。

mouseleave:類似“mouseout”,但不冒泡。在元素上方是不觸發。

mouseup:當使用者釋放滑鼠按鍵時觸發,不能夠通過鍵盤觸發。

傳遞給滑鼠事件處理常式的事件對象有clientX和clientY屬性,它們指定了滑鼠指標相對於包含視窗的座標。加入視窗的滾動位移量,就可以把滑鼠位置轉換成文檔座標。
頁面上的所有元素都支援滑鼠事件。除了mouseenter和mouseleave外,所有的事件都冒泡,並且他們的預設行為是可以被取消掉的。但取消滑鼠事件的預設行為可能會影響到其他事件,因為有些滑鼠事件是相互依賴的。

拖拉事件 

(1)drag事件
 drag事件在來源物件被拖拉過程中觸發。
(2)dragstart,dragend事件
 dragstart事件在使用者開始用滑鼠拖拉某個對象時觸發,dragend事件在結束拖拉時觸發。
(3)dragenter,dragleave事件
 dragenter事件在來源物件拖拉進目標對象後,在目標對象上觸發。dragleave事件在來源物件離開目標對象後,在目標對象上觸發。
(4)dragover事件
 dragover事件在來源物件拖拉過另一個對象上方時,在後者上觸發。
(5)drop事件

 當來源物件被拖拉到目標對象上方,使用者鬆開滑鼠時,在目標對象上觸發drop事件。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.