一 簡述JavaScript及其在瀏覽器中的地位 (一) 瀏覽器主要構成 雖然不同瀏覽器之間存在差異(如Google Chrome,Firefox,Safari和IE等),但單從瀏覽器構成來說,大同小異,大致可歸結為如下幾類: 1.User Interface(用戶界面):所謂用戶界面,就是通過瀏覽 ...
一 簡述JavaScript及其在瀏覽器中的地位
(一) 瀏覽器主要構成
雖然不同瀏覽器之間存在差異(如Google Chrome,Firefox,Safari和IE等),但單從瀏覽器構成來說,大同小異,大致可歸結為如下幾類:
1.User Interface(用戶界面):所謂用戶界面,就是通過瀏覽器渲染出來,讓用戶可見的界面,如地址欄,書簽菜單欄等;
2.Browser Engine(瀏覽器引擎):主要操作呈現的引擎界面;
3.Rendering Engine(渲染引擎):負責渲染響應請求內容,如負責解析HTML和CSS;
4.Networking(網路):負責網路呼叫處理,如http請求;
5.JS Interpreter(JavaScript 解釋器):負責解析和執行javascript代碼;
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/。
- 極少部分文章利用讀書、參考、引用、抄襲、複製和粘貼等多種方式整合而成的,大部分為原創。
- 如您喜歡,麻煩推薦一下;如您有新想法,歡迎提出,郵箱:[email protected]。
- 可以轉載該博客,但必須著名博客來源。