淺談JavaScript之事件(上)

一  簡述JavaScript及其在瀏覽器中的地位javascript

(一)  瀏覽器主要構成html

雖然不一樣瀏覽器之間存在差別(如Google Chrome,Firefox,Safari和IE等),但單從瀏覽器構成來講,大同小異,大體可歸結爲以下幾類:java

1.User Interface(用戶界面):所謂用戶界面,就是經過瀏覽器渲染出來,讓用戶可見的界面,如地址欄,書籤菜單欄等;後端

2.Browser Engine(瀏覽器引擎):主要操做呈現的引擎界面;瀏覽器

3.Rendering Engine(渲染引擎):負責渲染響應請求內容,如負責解析HTML和CSS;cookie

4.Networking(網絡):負責網絡呼叫處理,如http請求;網絡

5.JS Interpreter(JavaScript 解釋器):負責解析和執行javascript代碼;dom

6.UI Back(UI後端):用於繪製組合框和窗口等基本組建;異步

7.Data Persistence(數據持久):一般用來持久化存儲少許數據,如cookie等;函數

 

(二)JavaScript在瀏覽器中的地位

 如上圖,javascript處於瀏覽器中的核心位置,負責解釋和執行js腳本,內置於瀏覽器中,經過瀏覽器提供的API來訪問。

(三)JavaScript構成

關於javascript的構成,大體可歸結爲三個部分:ECMAScript,DOM和BOM。

1.ECMAScript是對js的約束和規範,如基本語法結構;

2.DOM就是文檔對象模型,是交互的資源,如html文檔;

3.BOM主要是對瀏覽器自己描述,如瀏覽器名稱,版本號等;

 

(四)JavaScript基本執行原理

 這裏不深刻談及javascript的深層次執行原理,只是大體描述一下,關於更深層次的,在後續文章推出,與你們分享。

 JS的執行原理,用一句話來歸結之:單線程異步。下圖很好地表述該過程。

全部的執行函數統一放在隊列中進行排隊。

 

二  事件流

所謂事件流,也可理解爲事件的軌跡。通常地,將事件流分爲三個階段:捕獲階段,目標階段和冒泡階段。

下圖爲三個階段的大體流程圖。

 (一)捕獲階段

捕獲階段處於事件流的第一階段,該階段的主要做用是捕獲截取事件。在DOM中,該階段始於Document,結束於body(固然,在如今的很

多高版本瀏覽器中,該過程結束於目標元素,只不過不執行目標元素而已,這也體現了目標元素具備雙重範圍)。

 

 (二)目標階段

目標階段處於事件流的第二階段,該階段的主要做用是執行綁定事件。通常地,該階段具備雙重範圍,即捕獲階段的結束,冒泡階段的開始;

(三)冒泡階段

冒泡階段處於事件流的第三階段,該階段的主要做用是將目標元素綁定事件執行的結果返回給瀏覽器,處理不一樣瀏覽器之間的差別,主要在該階段完成。

(四)三階段在Dom中的完整流程

 

三   事件處理程序

js事件處理程序按照種類來劃分,大體可分爲五大類:HTML事件處理程序,DOM0級事件處理程序,DOM2級事件處理程序,IE事件處理程序和跨瀏覽器事件處理程序。

尤爲是DOM0,DOM2和IE事件處理程序,利用它們之間的差別化有效地解決瀏覽器差別問題,從而實現跨瀏覽器的兼容性問題。

 

(一)html事件處理程序

所謂html事件處理程序,就是在dom結構中嵌套js代碼。在html中,元素支持的全部事件,均可以使用與相應事件處理程序同名的html特性來指定,這個特性的值應該是能執行的js代碼。

如點擊事件。

<body>
    <!--html事件處理程序-->
    <input type="button" value="請點擊" onclick="alert('測試html事件處理程序!!')"/>
</body>

固然,通常不採用如上方法,常規的作法是,將js代碼定義在目標元素外部。所以,與如上相同功能的定義爲:

目標元素

<body>
    <!--html事件處理程序-->
    <input type="button" value="請點擊" onclick="HtmlEventHandlerProc()"/>
</body>

外部js

<script>
    function HtmlEventHandlerProc() {
        alert('測試html事件處理程序!!');
    }
</script>

Tip:

1.事件處理程序中的代碼,可以訪問全局做用域中的任何變量;

2.每一個function()存在一個局部變量,即事件對象event,經過event變量,能夠直接訪問事件對象。

<body>
   <input type="button" value="請點擊" onclick="alert(event.type)"/>
</body>

執行結果

3.在函數內部,this值等於事件的目標元素。

<body>
    <input type="button" value="請點擊" onclick="alert(this.value)"/>
</body>

執行結果

 this具備擴展做用域的功能,其功能至關於

function myfunction() {
        with (document) {
            with (this) {
                //add your logic
           }
      }
 }

若是當前元素是一個表單元素,則做用域還會包含訪問表單元素(父元素)的入口。

  function myfunction() {
        with (document) {
            with (this.form) {
                with (this) {
                    //add your logic
                }
            }
        }
    }

這樣作,有什麼本質意義呢?固然是想讓事件處理程序更快捷訪問表單其餘字段(無需引用表單元素就能訪問)

 <form>
         <input type="text" name="userName" value="Alan_beijing" />
         <input type="button" value="測試表單元素" onclick="alert(userName.value)" />
     </form>

執行結果

 4.html事件處理程序存在哪些缺點?

   缺點一:時差問題

   缺點二:擴展的做用域鏈在不一樣瀏覽器中會致使不一樣結果

   缺點三:html代碼與js代碼高度耦合

(二)DOM0級事件處理程序

DOM0級事件很好地解決了html和js代碼強耦合的問題。

1.爲元素綁定事件

var btn = document.getElementById('myBtn');
btn.onclick = function () {
    alert('Clicked');
}

2.爲元素解除事件

btn.onclick = null;

(三)DOM2級事件處理程序

DOM2級事件定義了兩個方法來爲目標元素綁定事件處理程序(addEventListener())和解除事件處理程序(removeEventListener()),全部節點中都包含這兩個方法,而且他們都接收三個參數:

要處理的事件名,事件處理程序和一個布爾值(true表示是在捕獲階段進行,false表示在冒泡階段進行)

1.爲事件添加click事件處理程序(冒泡階段進行)

var btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
     alert(this.id);
}, false);

執行結果:

2.添加多個事件處理程序

var btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
   alert(this.id);
}, false);

btn.addEventListener(
"click", function myfunction() { alert("添加的第二個事件處理程序"); }, false);

執行結果:

 3 移除事件處理程序

經過addEventListener()添加的事件處理陳旭只能使用removeEventListener()來移除,移除時,傳入的參數與添加的程序時使用的參數相同

(這意味着匿名函數不能經過removeEventListener()來刪除)

匿名函數不能刪除

var btn = document.getElementById("myBtn");
    btn.addEventListener("click", function () {
        alert(this.id);
    }, false);

    //不能刪除,由於是匿名函數
    btn.removeEventListener("click", function () {
        alert(this.id);
    }, false);

非匿名函數能刪除

    var btn = document.getElementById("myBtn");
    var handler = function () {
        alert(this.id);
    };

    btn.addEventListener("click", handler, false);
    //刪除事件處理程序
    btn.removeEventListener("click", handler, false);

(四)IE事件處理程序

IE提供了兩個方法來綁定和卸載事件處理程序,attachEvent()和detachEvent(),這兩個方法均接收兩個參數,即事件處理程序名稱和事件處理程

序函數,而且在冒泡階段添加(IE8及更早版本只支持冒泡)

1.爲目標按鈕添加綁定事件

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function () {
   alert("IE事件處理程序!!");
});

2.爲目標按鈕添加綁定事件

多個執行綁定事件的結果是倒過來的。

 var btn = document.getElementById("myBtn");
 btn.attachEvent("onclick", function () {
       alert("IE事件處理程序1!!");
 });

 btn.attachEvent("onclick", function () {
      alert("IE事件處理程序2!!");
 });

3.爲目標元素移除事件處理程序

注意:匿名事件處理程序是不可以移除的

    var btn = document.getElementById("myBtn");
    var handler = function () {
        alert("IE事件處理程序");
    };
    //綁定事件
    btn.attach("onclick", handler);
    //移除事件
    btn.detachEvent("onclick", handler);

(五)跨瀏覽器事件處理程序

在跨瀏覽器中,無非就是三種選擇:DOM0級選擇(不經常使用,基本被廢棄),DOM2級選擇和IE選擇(不經常使用,IE8及如下版本)。

//定義EventUtil
    var EventUtil = {
        addHandler: function (element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent("on" + type, handler);
            }
        },
        removeHandler: function (element, type, handler) {
            if (element.removeEventListener) {
                element.removeEventListener(type, handler, false);
            } else if (element.detachEvent) {
                element.detachEvent("on" + type, handler);
            } else {
                element["on" + type] = null;
            }
        }
    }

    //調用
    var btn = document.getElementById("myBtn");
    var handler = function () {
        alert("事件處理程序跨瀏覽器!!");
    };
    //綁定事件處理程序
    EventUtil.addHandler(btn, "click", handler);
    //移除事件處理程序
    EventUtil.removeHandler(btn, "click", handler);

四  事件類型

內容相對比較簡單,這裏就暫且列舉主要內容,如有須要,會在下篇文章論述。

五  事件對象及其事件委託

介於文章篇幅有限,暫且列舉主要內容,代碼部分將在下篇文章論述。

六  版權區

  • 感謝您的閱讀,如有不足之處,歡迎指教,共同窗習、共同進步。
  • 博主網址:http://www.cnblogs.com/wangjiming/。
  • 極少部分文章利用讀書、參考、引用、抄襲、複製和粘貼等多種方式整合而成的,大部分爲原創。
  • 如您喜歡,麻煩推薦一下;如您有新想法,歡迎提出,郵箱:2098469527@qq.com。
  • 能夠轉載該博客,但必須著名博客來源。
相關文章
相關標籤/搜索