標籤:javascript 事件
事件其實在第一次學習JavaScript的時候就接觸了,一行非常簡單的代碼 alert(‘Hello JavaScript!!!‘)就詮釋了什麼是事件。事件是什麼呢?事件在基於瀏覽器編程的語言JavaScript中是一個非常非常重要的方法,遍地都是這種文法。什麼是事件呢?在JavaScript中事件可以理解為發生的一件事情,事件這個對象記錄了這個過程中所有的資料。
1.事件的相容性處理
准所周知,現在很多瀏覽器中分為標準瀏覽器陣營Chrome、FireFox等,非標準瀏覽器就是IE為代表了,在寫代碼的時候處處都要小心他們之間的相容問題,這是家常便飯了。事件也不例外同樣需要處理這些相容性的問題。
理解事件最重要的是上面提到的事件對象:
- IE/Chrome:event是一個內建對象
- FireFox:是通過事件函數的第一個參數將事件對象傳入
document.onclick = function(ev){ //在IE FireFox中顯示的內容完全不一樣,所以需要對事件進行處理 alert(event); //為了相容各種瀏覽器可以採用如下的寫法 var ev = ev || window.event ; var str = ‘‘; var i = 0 ; //在ev事件對象中儲存了事件發生過程中的所有資訊,遍曆事件對象中的資訊,輸出到頁面中觀察所有的資訊 for(var attr in ev){ ++i ; str += i + ‘ . ‘+ attr + ‘ ---> ‘ + ev[attr] + ‘<br>‘; } //將資訊添加到頁面中 document.body.innerHTML = str ;}
上面的代碼中var ev = ev || window.event ;使用了一種或的方式完成了非常完美的相容性問題。其實在JavaScript中還有一種完美的方法處理相容性的問題就是用if....else ...進行判斷,這兩種方法給我處理相容性問題提供了非常好的解決方案。
2.事件冒泡及案例
1.事件冒泡
事件冒泡非常經典的案例,不多說了,上一段網上非常經典的代碼直接看結果,就理解是怎麼回事了?
<script type="text/javascript"> window.onload = function(){ //擷取頁面中的三個元素對象 var objDiv1 = document.getElementById(‘div1‘); var objDiv2 = document.getElementById(‘div2‘); var objDiv3 = document.getElementById(‘div3‘); //事件函數,將當前ID進行顯示 function func(){ alert(this.id); } //給三個DIV同時綁定一個事件函數 objDiv1.onclick = func ; objDiv2.onclick = func ; objDiv3.onclick = func ; }</script><!-- 三個DIV在物理上是包含的關係--><div id="div1"> <div id="div2"> <div id="div3"></div> </div></div>
點擊DIV3發現彈出了三個結果,事實上只給DIV3綁定了一個事件函數。這就是典型的事件冒泡。有的網友說和DIV的物理位置有關,其實和DIV之間的內含項目關聯性有關,和物理上的定位關係沒有半毛錢的關係的,做個實驗就知道了。
2.利用事件冒泡的案例
下面的案例類比的是網頁側邊欄分享功能的實現,當滑鼠移動到網頁側邊欄分享的時候就出現一個DIV可以選擇分享到那個網站上面的列表,可以將“分享到”放到子DIV中利用事件冒泡原理,將事件的處理給父級DIV處理。這樣就很輕鬆實現了,如下代碼:
<style type="text/css"> #box{width: 100px;height: 250px;position: absolute;top: 200px;left: -100px;background: pink;} #slider{width: 20px;height: 90px;background: grey;position: absolute;right: -20px;top: 20px; text-align: center;font-size: 13px;}</style><script type="text/javascript"> window.onload = function(){ var objBox = document.getElementById(‘box‘); //滑鼠移入事件交給父級DIV處理 objBox.onmouseover = function(){ objBox.style.left = ‘0‘; } //滑鼠移出事件交給父級DIV處理 objBox.onmouseout = function(){ objBox.style.left = ‘-100px‘; } }</script><!-- 注意網頁結構 --><div id="box"> <div id="slider">點擊分享</div></div>
3.事件的綁定和捕獲的理解
1.什麼是事件綁定呢?
上面代碼中的這段objDiv1.onclick = func ;就是事件綁定。只是這種寫法有局限性,對於一個對象綁定兩個事件就無能為力了,下面的可能覆蓋上面的了。
function fn1(){ alert(this); //alert(‘JavaScript‘);}function fn2(){ alert(‘jQuery‘);}//下面的事件綁定覆蓋了上面的綁定事件document.onclick = fn1 ;document.onclick = fn2 ;
所以就誕生了事件的綁定函數attachEvent()和addEventListener()兩個函數 ,為啥有兩個呢?不多說了瀏覽器多,對付兩個陣營的瀏覽器的綁定事件的,所以還要處理相容性的問題,在處理相容性的問題,要搞清楚這個兩個綁定事件函數的區別如下代碼和分析:
function fn1(){ alert(this); //alert(‘JavaScript‘);}function fn2(){ alert(‘jQuery‘);}//非標準IE綁定事件函數document.attachEvent(‘onclick‘,fn1);document.attachEvent(‘onclick‘,fn2);//標準瀏覽器的綁定事件函數document.addEventListener(‘click‘,fn1,false); document.addEventListener(‘click‘,fn2,false);
仔細觀察上面的執行結果總結出如下區別:
非標準IE attachEvent(‘事件名稱’,‘事件函數’);
- 高版本IE執行時正序
- 事件名稱前面有on
- 事件沒有捕獲
- 調用的時候this指向window(this指標問題經常遇到)
標準:addEventListener(事件名稱,事件函數,是否捕獲);其中是否捕獲預設是false false:冒泡 true:捕獲
- 事件名稱沒有on
- 事件執行時正序
- 事件進行捕獲
這個時候可以封裝一個函數同意解決這個相容的問題如下:
//eventObj表示要綁定事件的對象,eventName綁定事件名稱,funName事件函數function bindEvent(eventObj,eventName,funName){ //標準瀏覽器 if(eventObj.addEventListener){ eventObj.addEventListener(eventName,funName,false); } else { //非標準瀏覽器 eventObj.attachEvent(‘on‘+eventName,function(){ //修正this指向問題 funName.call(eventObj); }); }}function fn1(){ alert(this);}//調用測試bindEvent(document,‘click‘,fn1);
上述中可能難理解的call()函數,call()函數就是調用函數的意思。和普通的調用一樣。其實call()是方法對象下面的一個方法,正常調用函數都是函數名加上括弧就可以調用了。還有一種方法就是函數名.call(參數一,參數二,參數三…);
- 參數一表示調用方法過後this指向的對象
- 參數二以後的參數都是函數的傳入參數
function fn3(arg1,arg2){ alert(this); alert(arg1 + arg2);}//document參數就是函數執行完畢要返回的對象,從第二個參數開始就是函數的參數了fn3.call(document,66,99);
2.事件的捕獲
上面綁定事件的函數中最後出現了一個參數,參數的意思就是是否捕獲事件的意思,那麼到底事件捕獲可以怎麼理解呢?
當設定false的時候事件向外冒泡
當設定true向內捕獲事件
一個是事件進來的時候觸發事件函數
一個是事件出去的時候觸發事件函數
通過下面的代碼就很容易理解了:
<script type="text/javascript"> window.onload = function(){ var objDiv1 = document.getElementById(‘div1‘); var objDiv2 = document.getElementById(‘div2‘); var objDiv3 = document.getElementById(‘div3‘); //觀察程式的執行順序 objDiv1.addEventListener(‘click‘,function(){ alert(3); },false); objDiv2.addEventListener(‘click‘,function(){ alert(1); },true) objDiv3.addEventListener(‘click‘,function(){ alert(2); },false); }</script><div id="div1"> <div id="div2"> <div id="div3"></div> </div></div>
注意分析上述代碼。
4.鍵盤事件
鍵盤事件中經常用到一下這些事件:
onkeydown:當鍵盤按下的時候觸發onkeyup:當鍵盤抬起的時候觸發ev.keyCode:鍵盤按鍵的值,數字類型ctrlKey,altKey,shiftKey:返回布爾值
類比聊天室的案例:
<script type="text/javascript"> window.onload = function(){ var objText = document.getElementById(‘txt‘); var objUl = document.getElementById(‘ulOne‘); //當按鍵抬起的時候觸發 objText.onkeyup = function(ev){ var ev = ev || window.event ; if(this.value != ‘‘){ if(ev.keyCode == 13 ){ var objLi = document.createElement(‘li‘); objLi.innerHTML = this.value ; if(objUl.children[0]){ objUl.insertBefore(objLi,objUl.children[0]); } else { objUl.appendChild(objLi); } //清空文字框中的內容 this.value = ‘‘; } } } }</script><input type="text" id="txt"><ul id="ulOne"></ul>
5.阻止事件的預設行為的方法
阻止事件的預設行為,例如常見的瀏覽器右鍵的時候自動彈出瀏覽器本身的綁定的右鍵事件,有時候寫程式不需要這些預設的事件,而是自己自訂事件,這個時候阻止預設事件可以在函數中使用 return false;
6.拖動案例
經常看到富文字框架中的panel可以進行視窗的變大和縮小,同時可以進行拖動。拖動是什麼原理呢?當滑鼠點擊DIV的時候發生onmousedown事件,滑鼠按下後移動滑鼠發生onmousemove事件,拖動到目的地後滑鼠要抬起的時候發生onmouseup事件,這就是整個拖動的原理。
var objDiv = document.getElementById(‘box‘);objDiv.onmousedown = function(ev){ //擷取事件對象 var ev = window.event || ev ; //計算滑鼠點擊點離DIV邊緣的距離 var disX = ev.clientX - objDiv.offsetLeft ; var disY = ev.clientY - objDiv.offsetTop ; document.onmousemove = function(ev){ var ev = window.event || ev ; objDiv.style.left = ev.clientX - disX + ‘px‘; objDiv.style.top = ev.clientY - disY + ‘px‘; } document.onmouseup = function(){ document.onmousemove = document.onmouseup = null ; }}
今天內容確實多了點,太累了,洗洗睡覺了。。。
非常高興和大家交流學習
自由轉載,創意許可,請文章來源,來自這裡
(http://blog.csdn.net/unikylin)
JavaScript中事件回顧