欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

探究JavaScript中的五種事件處理程序方式

 更新時間:2016年12月07日 10:19:24   作者:918之初  
本篇文章主要介紹了JavaScript中的五種事件處理程序方式,具有一定的參考價值,有需要的可以了解一下。

我們知道JavaScript與HTML之間的交互是通過事件實現(xiàn)的。事件最早是在IE3和Netscape Navigator 2中出現(xiàn)的,當時是作為分擔服務器運算負載的一種手段。  通俗地理解,事件就是用戶或瀏覽器自身執(zhí)行的某種操作。而事件處理程序即為響應某個事件的函數。抽出主干,即事件處理程序為函數。  我們又把事件處理程序稱為事件偵聽器。  事件處理程序是以"on"開頭的,因此對于事件on的時間處理程序即為onclick。時間處理程序在JavaScript中大致有五種,下面會根據這五種不同的時間處理程序分為5部分來介紹。

1.HTML事件處理程序

2.DOM0級事件處理程序

3.DOM2級事件處理程序

4.IE事件處理程序

5.跨瀏覽器的事件處理程序

第一部分:HTML事件處理程序

什么使HTML事件處理程序呢?顯然,通過名字就可以猜到,它是卸載HTML中的函數(事件處理程序)。初學者大多用到的事件處理程序即為HTML事件處理程序。下面舉例:

例1:

<button onclick="alert('success')">點我</button>

這條代碼即為事件處理程序,點擊button后,會彈出彈框,顯示success。

特點:HTML事件處理程序中Javascript代碼作為了onclick特性的值,因此,我們不能在JavaScript代碼中使用未經轉義的HTML語法字符,如&(和號)、""(雙引號)、<(小于號)、>(大于號)等等。所以這個例子中字符串我使用了單引號而沒有使用雙引號。看下面在JavaScript代碼中使用了未經轉義的HTML語法字符。

 例2:

<button onclick="alert("success")">點我</button>

這時,我在success外使用了HTML語法字符""(雙引號),這時不會彈出窗口,而是報錯語法錯誤。但是我如果還是希望使用雙引號呢? 這時就要用&quot;實體來代替HTML中的語法字符。如下例所示:

例3:

<button onclick="alert(&quot;success&quot;)">點我</button>
  <!-- 正常彈出窗口-->

這個例子中我們在JavaScript代碼中使用了HTML實體而沒有使用HTML語法字符,這時就不會報錯了。

 例4:

<button onclick="show()">點我</button>

<!-- 正常彈出窗口--> 

<script>

  function show(){

    alert("success");

  }

</script> 

這個例子中我們調用函數,而把函數定義放在了script中,這樣也是可以的。因為:事件處理程序中的代碼在執(zhí)行時,有權訪問到全局作用域中的任何代碼。這句話怎么理解呢?  實際上,我們可以在chrome中觀察button標簽的作用域鏈。如下所示:

接下來我們再看看script所在的作用域,如下圖所示:

可以看到script標簽就在全局作用域。

也就是說目前button中的HTML事件處理函數在作用域鏈的最前端,而Script在全局作用域,所以“事件處理程序中的代碼在執(zhí)行時,有權訪問到全局作用域中的任何代碼?!边@句話就不難理解了。

 例5:

<button onclick="alert(event.type)">點我</button>

這時瀏覽器彈出窗口顯示:click。這個例子是什么意思呢?注意到我并沒有在event.type外加單引號,說明這并不是字符串。實際上,event是局部對象--在觸發(fā)DOM上的某個事件時,會產生一個事件對象event,這個對象包含著所有與事件有關的信息。而這里是彈出了對象了類型,即為click。

 HTML事件處理程序的三個缺點(重點):

1. 時差問題。 因為用戶可能在HTML元素一出現(xiàn)就開始觸發(fā)相應事件,但是有可能該事件的腳本(如例4中show()函數的函數定義在script中)還沒有加載完成,此時不具備執(zhí)行條件,故報錯。

解決方法:將HTML事件處理程序封裝在一個try-catch塊中,以便錯誤不會浮出水面。

<input type="button" value="click me" onclick="try{show();}catch(ex){}">

2.這樣擴展事件實例程序的作用域鏈在不同的瀏覽器中會導致不同的結果(例4中我是在chrome中查看的作用域鏈,其他瀏覽器不一定是這樣的,請注意)。不同JavaScript引擎遵循的標識符解析規(guī)則略有差異,很有可能會在訪問非限定對象成員時出錯。

3.HTML和JavaScript代碼緊密耦合。 結果是:如果要更換事件處理程序,就必須改動兩個地方--HTML代碼和JavaScript代碼。

 那么怎么解決上面的問題呢? DOM0級事件處理程序是一個不錯的選擇!

第二部分:DOM0級事件處理程序

DOM0級事件處理程序用的也非常普遍。之所以成為DOM0級,我認為是當時還沒有出DOM標準,而IE和Netscape Navigator兩者使用的時間處理程序(不知是否合理,望批評指正)。 總之,我們先看看下面的例子吧。

例6:

<button id="button">點我</button>

<script>
  var button=document.getElementById("button");
  button.onclick=function(){
    alert("clicked");
  }
</script>

即我們先在script中取得元素的引用,然后再將一個函數賦值給onclick事件處理程序。 之前介紹過,事件處理程序即為函數,而button.onclick這種形式即函數作為了對象的方法。那么對象的方法即事件處理程序是在元素(對象)的作用域中運行而非在全局作用域中運行的,因為方法是屬于對象的。(注意:例4中事件處理程序是在全局作用域中運行的)。 如果這個函數中存在this關鍵字,那么this就會指向這個對象。下面我們在瀏覽器中證明事件處理程序是在元素的作用域中運行。

我們看到alert("clicked");確實是在button中運行的。

我們還可以通過下面的方式刪除通過DOM0級方法指定的事件處理程序。

button.onclick=null;

通過上面的分析我們可以知道DOM0級事件處理程序是非常不錯的,它解決了HTML事件處理程序的三個缺點:時差問題、作用域鏈導致的不同瀏覽器表現(xiàn)不一致問題和HTML和JavaScript緊密耦合問題。

但是,DOM0級事件處理程序并不是完美的,它同樣有兩個缺點:

1.我們不能給一個元素同時添加兩個事件。

2.我們不能控制元素的事件流(捕獲or冒泡)。

對于第二個問題后面會講到,第一個問題舉例如下:

<button id="button">點我</button>

<script>
  var button=document.getElementById("button");
  button.onclick=function(){
    alert("clicked");
  }
  button.onclick=function(){
    alert("again");
  }

雖然我對同一個元素設置了兩個事件處理程序,但是最終的結果是:只有第二個事件有效(覆蓋了第一個事件)。當然,人類是聰明的動物,DOM2級事件很好的解決了這個問題!

第三部分:DOM2級事件處理程序

DOM2級事件處理程序定義了兩個方法:

  • addEventListener()   ---添加事件偵聽器
  • removeEventListener()   ---刪除事件偵聽器

在博文的開頭我就提到了事件處理程序即事件偵聽器。這兩個方法都接收三個參數:

1.要處理的事件名(注意:是時間名,所以沒有on?。?,如click、mouseover等。

2.作為事件處理程序的函數,如function(){alert("clicked");}

3. 表示事件流方式的布爾值。false為冒泡階段調用事件處理程序;true為捕獲階段調用事件處理程序。

下面通過兩個例子加深理解:

例7:

<button id="button">點我</button>

<script>
  var button=document.getElementById("button");
  button.addEventListener("click",function(){
    alert(this.id);
  },false);
  button.addEventListener("click",function(){
    alert("another event");
  },false);
</script>

結果:第一次彈出窗口:button。

   第二次彈出窗口:another event。

結論:通過DOM2級事件處理程序,我們可以為同一個元素添加兩個或更多的事件。事件根據順序依次觸發(fā)。且this同樣指向當前元素,故函數在元素的作用域中執(zhí)行。

this分析:和前面的DOM0級事件處理程序一樣,這里的addEventListener同樣也可以看作對象的方法,不同之初在于,DOM0級的方法需要另外一個函數來賦值,而這里的方法是DOM2級規(guī)范預定義的。

removeEventListener()這個刪除事件處理程序的方法值得注意的是:使用addEventListener()來添加的事件處理程序只能通過它來移除,且需要傳入相同的參數。

例8:

<button id="button">點我</button>

<script>
  var button=document.getElementById("button");
  button.addEventListener("click",function(){
    alert(this.id);
  },false);
  button.removeEventListener("click",function(){
    alert("another event");
  },false);

上述代碼貌似可以移除click的事件處理程序,但是通過實驗證明是不可以的,原因是:事件處理程序為匿名函數時無法移除。看下面的成功移除的例子:

 例9:

<button id="button">點我</button>

<script>
  var button=document.getElementById("button");
  function handler(){
    alert(this.id);
  }
  button.addEventListener("click",handler,false);
  button.removeEventListener("click",handler,false);
</script>

成功移除!

注意:1.傳入方法的handler沒有(),是因為這里都只是定義函數,而不是調用,需要注意。

   2.這兩個方法的第三個參數都是false,即事件處理程序添加到冒泡階段。一般不使用true,因為低版本的IE不支持捕獲階段。

 DOM2級事件處理程序成功地解決了前面所有事件處理程序的問題,堪稱perfect!!!!  然而總是特立獨行的IE瀏覽器又有新花樣,它也有自己的一套事件處理程序,下面我們就來看看吧。

 第四部分:IE事件處理程序

IE事件處理程序中有類似與DOM2級事件處理程序的兩個方法:

1.attachEvent()

2.detachEvent()

它們都接收兩個參數:

1.事件處理程序名稱。如onclick、onmouseover,注意:這里不是事件,而是事件處理程序的名稱,所以有on。

2.事件處理程序函數。如function(){alert("clicked");}

之所以沒有和DOM2級事件處理程序中類似的第三個參數,是因為IE8及更早版本只支持冒泡事件流。

注意:

1.IE事件處理程序中attachEvent()的事件處理程序的作用域和DOM0與DOM2不同,她的作用域是在全局作用域中。因此,不同于DOM0和DOM2中this指向元素,IE中的this指向window。

2.同樣,我們可以使用attachEvent()來給同一個元素添加多個事件處理程序。但是與DOM2不同,事件觸發(fā)的順序不是添加的順序而是添加順序的相反順序。

3.同樣地,通過attachEvent()添加的事件處理程序必須通過detachEvent()方法移除,同樣的,不能使用匿名函數。

4.支持IE事件處理程序的瀏覽器不只有IE瀏覽器,還有Opera瀏覽器。

第五部分:跨瀏覽器的事件處理程序

實際上,這一部分視為了跨瀏覽器使用,將前面的幾部分結合起來就可以了。

這一部分需要創(chuàng)建兩個方法:

  • addHandler()  --這個方法職責是視情況來使用DOM0級、DOM2級、IE事件處理程序來添加事件。
  • removeHandler()--這個方法就是移除使用addHandler添加的事件。

這兩個方法接收相同的三個參數:

1.要操作的元素--通過dom方法獲取

2.事件名稱--注意:沒有on,如click、mouseover
3.事件處理程序函數--即handler函數

這兩個方法的構造情況如下:

var EventUtil={
  addHandler:function(element,type,handler){
    if(element.addEventListener){
      element.addEventListener(type,handler,false);//注意:這里默認使用了false(冒泡)
    }else if(element.attachEvent){
      element.attachEvent("on"+type,handler);
    }else{
      element["on"+type]=handler;
    }
  },
  removeHandler:function(element,type,handler){
    if(element.removeEventListener){
      element.removeEventListener(type,handler,false);//注意:這里默認使用了false(冒泡)
    }else if(element.detachEvent){
      element.detachEvent("on"+type,handler);
    }else{
      element["on"+type]=null;
    }
  }
};

 即先判斷DOM2級事件處理程序,再判斷IE事件處理程序,最后使用DOM0級事件處理程序。

例10:通過這個例子來使用上面構造的方法。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>跨瀏覽器事件處理程序</title>
</head>
<body> 

  <button id="button">點我</button>

<script>
var EventUtil={
  addHandler:function(element,type,handler){
    if(element.addEventListener){
      element.addEventListener(type,handler,false);//注意:這里默認使用了false(冒泡)
    }else if(element.attachEvent){
      element.attachEvent("on"+type,handler);
    }else{
      element["on"+type]=handler;
    }
  },
  removeHandler:function(element,type,handler){
    if(element.removeEventListener){
      element.removeEventListener(type,handler,false);//注意:這里默認使用了false(冒泡)
    }else if(element.detachEvent){
      element.detachEvent("on"+type,handler);
    }else{
      element["on"+type]=null;
    }
  }
};

  function handler(){
    alert("clicked");
  }

  var button=document.getElementById("button");
  EventUtil.addHandler(button,"click",handler);
</script>
</body>
</html>

最后瀏覽器成功彈出“clicked”。

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

相關文章

  • JS變量及其作用域

    JS變量及其作用域

    本文主要介紹了JS變量及其作用域的相關知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-03-03
  • javascript 獲取多條數據(模擬ajax獲取數據)

    javascript 獲取多條數據(模擬ajax獲取數據)

    javascript 獲取多條數據(模擬ajax獲取數據),這樣的好處不用額外的ajax讀取鏈接,減輕服務器負擔。
    2009-06-06
  • 初學JavaScript_03(ExtJs Grid的簡單使用)

    初學JavaScript_03(ExtJs Grid的簡單使用)

    Ext JS Grid的簡單使用:(從土豆的文檔中學到)
    2008-10-10
  • BootStrap輪播HTML代碼(推薦)

    BootStrap輪播HTML代碼(推薦)

    本文給大家分享bootstrap輪播h tml代碼,代碼簡單易懂非常不錯,具有參考借鑒,需要的朋友參考下吧
    2016-12-12
  • JavsScript中Promise的錯誤捕獲詳解

    JavsScript中Promise的錯誤捕獲詳解

    怎么捕獲錯誤并且處理是一門語言必備的知識,在JavaScript中也是如此,下面這篇文章主要給大家介紹了關于JavsScript中Promise錯誤捕獲的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • Javascript中Microtask和Macrotask鮮為人知的知識點

    Javascript中Microtask和Macrotask鮮為人知的知識點

    這篇文章主要為大家介紹了Javascript中Microtask和Macrotask鮮為人知的知識點講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • JavaScript中fetch()用法實例

    JavaScript中fetch()用法實例

    在前端快速發(fā)展地過程中,為了契合更好的設計模式,產生了 fetch 框架,下面這篇文章主要給大家介紹了關于JavaScript中fetch()用法的相關資料,需要的朋友可以參考下
    2022-06-06
  • 深入理解JavaScript系列(35):設計模式之迭代器模式詳解

    深入理解JavaScript系列(35):設計模式之迭代器模式詳解

    這篇文章主要介紹了深入理解JavaScript系列(35):設計模式之迭代器模式詳解,迭代器模式(Iterator):提供一種方法順序一個聚合對象中各個元素,而又不暴露該對象內部表示,需要的朋友可以參考下
    2015-03-03
  • 如何使用50行javaScript代碼實現(xiàn)簡單版的call,apply,bind

    如何使用50行javaScript代碼實現(xiàn)簡單版的call,apply,bind

    這篇文章主要介紹了50行javaScript代碼實現(xiàn)簡單版的call,apply,bind過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • 微信小程序實現(xiàn)本地分頁加載

    微信小程序實現(xiàn)本地分頁加載

    這篇文章主要為大家詳細介紹了微信小程序實現(xiàn)本地分頁加載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08

最新評論