DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> JavaScript高級程序設計 事件學習筆記
JavaScript高級程序設計 事件學習筆記
編輯:關於JavaScript     

第12章 事件
1.事件流
1.1事件冒泡(IE事件流)
□事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接受,然後逐級向上傳播到較為不具體的節點(文檔)。
□所有浏覽器均支持事件冒泡。Firefox、chrome、safari將事件一直冒泡到window對象。
1.2事件捕獲(Netscape事件流)
□不太具體的節點更早收到事件,而具體的節點最後收到節點。
□Safari、chrome、Opera、firefox支持,但從window對象開始捕獲(DOM2級規范是從document開始)。
1.3DOM事件流
□“DOM2級事件”規定的事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。
□DOM2:捕獲階段不含實際目標,不涉及事件目標,只為截獲事件提供機會。
□Safari、chrome、Firefox和Opera9.5以上都會在捕獲階段觸發事件對象上的事件。結果有兩個機會在目標上操作事件。
□IE不支持DOM事件流。其他支持。
2.事件處理程序(或事件偵聽器)
定義:響應某個事件的函數。
2.1 HTML事件處理程序
□某個元素支持的每種事件,都可以使用一個相應事件處理程序同名的HTML特性來指定。
□其中的函數代碼字符需經過HTML轉義。
□存在問題:
◇時差問題:當觸發事件時,事件處理程序有可能尚不具執行條件。使用try-catch塊封裝,以便錯誤不會浮出水面。
<input type="button" value="click me" onclick="try{show();}catch(ex){}"/>
◇HTML與JavaScript代碼緊密耦合。
2.2 DOM0級事件處理程序
□DOM0級事件處理程序:將一個函數賦值給一個事件處理程序屬性。優點:簡單、跨浏覽器。
□這種方式的事件處理程序在代碼運行以前不會綁定事件。
□使用DOM0級方法指定的事件處理程序被認為是元素的方法。事件處理程序在元素作用域中運行;程序中this引用當前元素。
□刪除DOM0級事:btn.onclick = null; //刪除事件處理程序
2.3 DOM2級事件處理程序
□addEventListener()和removeEventListener()。接受3個參數:要處理的事件名、作為事件處理程序的函數和一個布爾值。
◇如果最後這個布爾值是true,表示捕獲階段調用事件處理程序;如果是false表示冒泡階段調用事件處理程序。
Var btn = document.getElementById("myBtn");
Btn.addEventListener("click",function(){alert(this.id);},false);
□使用DOM2級方法添加事件處理程序的主要好處是可以添加多個事件處理程序。按添加順序觸發。
□通過addEventListener()添加的事件處理程序只能使用removeEventListener()來移除;移除時傳入的參數與添加處理程序時使用的參數相同。即匿名函數無法移除。
□將事件處理程序添加到冒泡階段,得到最大限度兼容。
□Firefox、Safari、Chrome和Opera支持DOM2級事件處理程序。IE不支持,有獨有的事件處理程序。
2.4 IE事件處理程序。
□IE中與DOM2類似方法:attachEvent()和detachEvent()。這兩個方法接受相同的兩個參數:事件處理程序名稱與事件處理程序函數。
□IE僅支持冒泡,通過attachEvent()添加的事件處理程序都被添加到冒泡階段。
□attachEvent()中事件處理函數會再全局作用域中運行,因此this等於window。
□attachEvent()也可以為元素添加多個處理程序,以相反的書序觸發。
□attachEvent()事件可通過detachEvent()移除,匿名函數無法移除。
2.5 跨浏覽器的事件處理程序
var EventUtil = {
addHandler : function(element, type, handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element.attachEvent("on" + type, handler);
}else{
elmenet["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;
}
}
};
□此兼容函數沒有考慮到浏覽器的所有問題,如IE中作用域問題。
3.事件對象
定義:在觸發DOM的某個事件時,會產生一個事件對象event,這個對象中包含著所有與事件有關的信息。
3.1DOM中的事件對象
①兼容DOM的浏覽器會將一個event對象傳入到事件處理程序中(DOM0級或DOM2級)。通過HTML特性指定時,event變量保存event對象。
②所有event對象均包含以下屬性/方法。P291
□bubbles:表明事件是否冒泡,bool。
□cancelable:表明是否可以取消事件的默認行為,bool。
□currentTarget:其事件處理程序當前正在處理事件的那個元素。
□detail:與事件相關的細節信息。
□eventPhase:調用事件處理程序的階段:1.捕獲 2.處於目標 3.冒泡。
□preventDefault():取消事件默認行為。
□stopPropagation():取消事件的進一步捕獲或冒泡。
□target:事件的目標。
□type:被觸發的事件類型。
□view:與事件關聯的抽象視圖。
③在事件處理程序內部:
□對象this始終等於currentTarget的值,即this和currentTarget均指向綁定該事件程序的元素。
□target則只包含事件的實際目標,即觸發事件的元素。
④event.preventDefault():可取消特定事件的默認行為。
⑤event.stopPropagation():立即停止事件在DOM中的傳播。
⑥通過eventPhase屬性確定事件當前正位於事件流哪個階段。
3.2 IE中的事件對象
①訪問IE中的event對象,取決於指定的事件處理程序方法。
□使用DOM0級方法添加事件處理程序時,event對象作為window對象的一個屬性存在。
□使用attachEvent()添加,則有一個event對象作為參數傳入。同時也可以通過window.event訪問。
□通過HTML特性指定事件處理程序時,可以通過一個名叫event的變量訪問event對象。
②IE中所有的event對象包含以下屬性/方法:
□cancelBubble:默認為false,設為true可取消事件冒泡(類似DOM中的stopPropagation()方法)
□returnValue:默認為true,設為false可取消事件默認行為。(類似DOM2中的preventDefault()方法)
□srcElement:事件的目標(與DOM2中target屬性相同)
□type:被觸發的事件類型。
3.3 跨浏覽器的事件對象
var eventUtil = {
getEvent : function(event){
Return event ? Event : window.event;
},
getTarget : function(event){
return event.target || event.srcElement;
},
preventDefault : function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},
stopPropagation : function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
};
4.事件類型
□鼠標事件,當用戶通過鼠標在頁面上執行操作時觸發;
□鍵盤事件,當用戶通過鍵盤在頁面上執行操作時觸發;
□HTML事件,當浏覽器窗口發生變化或發生特定的客戶端/服務器交互時觸發。
□變動(mutation)事件,當底層DOM結構發生變化時觸發。
4.1 UI事件
UI事件主要與元素焦點相關,僅在兼容DOM的浏覽器中受到支持:
□DOMActive:表示元素已經被用戶操作(通過鼠標或鍵盤)激活;
□DOMFocusIN:表示元素已經獲得焦點;為HTML中focus事件的普通版;
□DOMFocusOut:表示元素已經失去焦點;為HTML中blur事件的普通版;
△由於支持的浏覽器很少,不推薦使用。
4.2 鼠標事件
①DOM中定義了7個鼠標事件,頁面上所有元素都支持鼠標事件:
□click:在用戶單擊主鼠標按鈕(一般式左邊的按鈕)或者按下回車鍵時觸發。
□dblclick:在用戶雙擊主鼠標按鈕(一般是左鍵)時觸發。
□mousedown:在用戶按下了任意鼠標按鈕時觸發。不能通過鍵盤觸發這個事件。
□mouseout:在鼠標指針位於一個元素上方,然後用戶將其移入另一個元素時觸發。新移入的元素可能在舊元素外部,也可以是其子元素。不能通過鍵盤觸發。
□mouseover:在鼠標指標為於一個元素外部,然後用戶將其首次移入另一個元素邊界之內時觸發。不通過鍵盤觸發。
□mouseup:在用戶釋放鼠標按鈕時觸發。不通過鍵盤觸發。
□mousemove:當鼠標指針在元素內部移動時重復地觸發。不能通過鍵盤觸發。
②注意事項:
□同一個元素上相繼觸發mousedown和mouseup事件才會觸發click事件。如果mousedown或mouseup其中之一取消,就不會觸發click事件。
□同一元素連續兩次觸發click事件,才會觸發dblclick事件。
4.2.1 客戶區坐標位置
□鼠標事件都是在浏覽器視口中的特定位置發生的。這個位置信息保存在事件對象(event)中的clientX和clientY屬性中。
4.2.2 屏幕坐標位置
□鼠標事件發生時,還有一個相對於整個電腦屏幕的位置。保存在事件對象(event)中的screenX和screenY屬性中。
4.2.3 修改鍵
□雖然鼠標事件主要是使用鼠標來觸發,但按下鼠標時鍵盤上的某些鍵也可以影響到所需操作。
□修改鍵為:Shift、Ctrl、Alt和Meta(蘋果中cmd鍵、windows中windows鍵)。
□DOM中表示這4個鍵的布爾值屬性:(在鼠標事件的event中)shiftKey、ctrlKey、altKey和metaKey(IE不支持metaKey)。
4.2.4 相關元素
發生mouseover和mouseout事件時,會涉及更多元素。兩事件都會涉及把鼠標指針從一個元素的邊界之內移動到另一個元素的邊界之內。
□DOM通過evnet對象的relatedTarget屬性提供了相關元素信息。
□IE不支持relatedTarget屬性。
◇在mouserover事件觸發時,IE的fromElement屬性中保存了相關元素。
◇在mouseout事件觸發時,IE的toElement屬性保存了相關元素。
□兼容方式:
var eventUtil = {
getRelatedTarget : function(event){
if(event.relatedTarget){
return event.relatedTarget;
}else if(event.toElement){
return event.toElement;
}else if(event.fromElement){
return event.fromElement;
}else{
return null;
}
}
};
4.2.5 鼠標按鈕
□click事件:單擊鼠標主鍵觸發,無必要檢測按鍵信息。
□mousedown和mouseup事件,在其event對象中有一button屬性表示按下或釋放的按鈕。
□DOM中的button屬性取值:
◇0表示主鼠標按鍵
◇1鼠標中鍵(滾輪按鈕)
◇2鼠標次鍵
□IE提供的button屬性
◇0沒按鍵◇1按主鍵◇2按次鍵◇3同時主+次◇4中鍵◇5主+中◇6次+中◇7主+次+中
□兼容代碼
getButton : function(event){
if(document.implementation.hasFeature("MouseEvents","2.0")){
return event.button;
}else{
switch(event.button){
case 0 :
case 1 :
case 3 :
case 5 :
case 7 :
return 0;
case 2 :
case 6 :
return 2;
case 4 :
return 1;
}
}
}
};
□如果不是按下或釋放主鍵,opera不會觸發mouseup或mousedown
4.2.6 更多的事件信息
□DOM2中detail屬性:元素單擊次數,離離開元素後清0.
□IE為鼠標增加更多信息。(僅IE支持,並無實用價值)。
4.2.7移動Safari
面向iPhone和Ipod中Safari開發時:
□不支持dblclick事件。雙擊Safari窗口會放大畫面,無法改變該行為。
□輕擊可單擊元素先觸發mousemove事件,若導致內容變化則無其他事件發生。若無內容變化,一次發生mousedown、mouseup和click。
□mousemove事件也會觸發mouseover和mouseout事件。
4.2.7 易訪問性問題
屏幕閱讀器只可通過click來觸發事件。使用鼠標事件時應該注意:
□使用click事件執行代碼
□不要使用onmouseover向用戶顯示新選項。屏幕閱讀器無法觸發。
□不要使用dblclick執行重要操作。鍵盤無法觸發。
4.3 鍵盤事件
①對鍵盤事件的支持主要遵循DOM0級。“DOM3級”為鍵盤事件制定了規范。
②3個鍵盤事件:
□keydown:當用戶按下鍵盤上的任意鍵時觸發,而且如果按住不放的話,會重復觸發此事件。
□keypress:當用戶按下鍵盤上的字符鍵時觸發,而且如果按住不放的話,會重復觸發此事件。
□keyup:當用戶釋放鍵盤上的鍵時觸發。
□與鼠標事件一樣,支持相同的修改鍵。而且鍵盤事件對象中也有shifKey、ctrlKey、altKey、metaKey屬性。
4.3.1 鍵碼
①發生keydown和keyup事件時,event對象的keyCode屬性會包含一個代碼與鍵盤上一個特定的鍵對應。
②keyCode屬性值與ASCII碼中對應小寫字母或數字的編碼相同。查表P304
③DOM和IE的event對象都支持keyCode屬性。
④以下是無論keydown或keyup事件都會存在的一些特殊情況:
□Firefox和Opera中,按分號鍵時keyCode值為59,即ASCII中值,但IE和Safari返回186,即鍵盤鍵碼
□Safari3之前版本中,上下左右,上下翻頁返回大於6300的值。
□在Opera9.5之前版本中,會將非數字字母鍵的keyCode設為ASCII編碼。
□在Safari3之前版本,不會因為按下了制表、上檔、控制或替代鍵而觸發keydown和keyup事件。
4.3.2 字符編碼
□Firefox、Chrome和Safari的event對象支持一個charCode屬性,這個屬性只有在發生keypress時才有值,為字符的ASCII編碼。此時的keyCode值有可能為0,也可能為所按鍵碼。
□IE和Opera則是在keyCode中保存ASCII編碼。
□跨浏覽器取字符編碼
var EventUtil = {
//省略的代碼
getCharCode : function(event){
if(typeof event.charCode == "number"){
return event.charCode;
}else{
return event.keyCode;
}
},
};
4.3.4 textInput事件
□當用戶在可編輯區域中輸入字符時,會觸發textInput事件。
◇只有編輯區域才能觸發textInput事件。
◇事件只會在用戶按下能夠輸入實際字符的鍵時才會被觸發。
◇事件event對象中包含一個data屬性,保存用戶輸入的字符。
□2008年上半年,僅Safari3和Chrome支持。
4.3.4 設備中的鍵盤事件。(略)
4.4 HTML事件
①定義:HTML事件指的是那些不一定與用戶操作有關的事件。
□load事件:
◇當頁面完全加載後window上面觸發。
◇當所有框架都加載完畢時在框架集上面觸發
◇當圖像加載完畢時在<img>元素上面觸發
◇當嵌入的內容加載完畢時在<object>元素上面觸發
□unload事件:
◇當頁面完全卸載後在window上面觸發
◇當所有框架都卸載後在框架集上面觸發
◇嵌入的內容卸載完畢後在<object>元素上面觸發
□abort事件:在用戶停止下載過程時,如果嵌入的內容沒有加載完,則在<object>元素上面觸發。
□error事件:
◇當發生JavaScript錯誤時在window上面觸發
◇當無法加載圖像時在<img>元素上面觸發
◇當無法加載嵌入內容時在<object>元素上面觸發
◇當有一或多個框架無法加載時在框架集上觸發
□select事件:當用戶選擇文本框(<input>或<textarea>)中的一個或多個字符時觸發。
□change事件:當文本框(<input>或<textarea>)失去焦點或者取得焦點後其值被改變時觸發。
□submit事件:當用戶單擊提交按鈕時在<form>元素上面觸發。
□reset事件:當用戶單擊重置按鈕時在<form>元素上觸發。
□resize事件:當窗口或框架的大小變化時在window或框架上觸發。
□scroll事件:當用戶滾動帶滾動條的元素中的內容時,在該元素上面觸發。<body>元素中包含所加載頁面的滾動條。
□focus事件:當頁面或元素獲得焦點(用戶單擊、按制表鍵進入或以其他方式激活元素時)在window及相應元素上面觸發。
□blur事件:當頁面或元素失去焦點時在window及相應元素上面觸發。
②多數HTML事件都與window對象或表單控件相關。要確定浏覽器是否支持DOM規定的HTML事件代碼如下:
Var isSupport = document.implementation.hasFeature("HTMLEvents","2.0");
4.4.1 加載(load)事件
①有兩種定義onload事件處理程序的方式
□EventUtil.addHandler(window,"load",function(event){alert("loaded");});
□為<body>元素添加一個onload特性(不建議)
②圖像上面也可以觸發load事件,無論是DOM中圖像還是HTML中的圖像元素。
□可以像使用<img>元素一樣使用image對象,不過無法添加到DOM樹中。
例子:使用Image對象在客戶端預加載圖像
EventUtil.addHandler(window,"load",function(){
var image = new Image();
EventUtil.addHandler(image,"load",function(event){
alert("Image loaded!");
});
image.src = "smile.gif";
});
③Firefox、Opera、Chrome和Safari3以上,<script>元素也會觸發load事件。與圖像不同,只有在設置了src並添加到文檔中才會開始下載JS文件。(IE不支持)
④IE和Opera還支持<link>元素上load事件。與<script>節點類似,在未指定href屬性並將<link>元素添加到文檔之前也不會開始下載樣式表。
4.4.2 卸載事件(unload)
□與load事件對應的是unload事件,這個事件在文檔完成卸載後觸發。
□利用這個事件最多的情況是消除引用,以免內存洩露。
□使用方式一:EventUtil.addHandler(window,"unload",function(event){alert("unload");});
□使用方式二:為<body>元素添加一個特性。
4.4.3 調整大小(resize)事件
①當浏覽器窗口被調整到一個新的高度或寬度時,就會觸發resize事件。
②事件在window(窗口)上觸發,因此可以通過JavaScript或<body>元素中的onresize特性來指定事件處理程序。
③IE、Safari、Chrome和Opera會再浏覽器窗口變化了1像素時觸發resize事件,然後隨著變化不斷重復觸發。因此不要加入大量計算代碼。
4.4.4 滾動(scroll)事件(略)
4.5 變動事件
①定義:DOM2級的變動(mutation)事件能在DOM中的某一部分發生變化是給出提示。
②DOM2級定義了如下變動事件:
□DOMSubtreeModified:在DOM結構中發生任何變化時觸發。
□DOMNodeInserted:在一個節點作為子節點被插入到另一個節點中時觸發。
□DOMNodeRemoved:在節點從其父節點中移除時觸發。
□DOMNodeInsertIntoDocument:在一個節點被直接插入文檔或通過子樹間接插入文檔之後觸發。在DOMNodeInsert之後觸發。
□DOMNodeRemovedFromDocument:在一個節點被直接從文檔中移除或通過子樹間接從文檔中移除之前觸發。這個事件在DOMNodeRemove之後觸發。
□DOMAttriModified:在特性被修改之後觸發。
□DOMCharacterDataModified:在文本節點的值發生變化時觸發。
③檢測浏覽器是否支持變動事件:
Var isSupport = document.implementation.hasFeature("MutationEvents","2.0");
□實際上,即使返回true也不代表浏覽器支持。P312
4.6 專有事件
4.6.1 上下文菜單(contextmenu事件)
①contextmenu事件:用以表示何時應該顯示上下文菜單,以便開發人員取消默認的上下文菜單而提供自定義的菜單。
②contextmenu事件是冒泡的,因此可以為document指定一個事件處理程序,用以處理頁面中發生的所有類似事件。
③事件的目標是發生用戶操作的元素,在所有浏覽器中都可以取消這個事件:兼容的DOM的:event.preventDefault(),在IE中,event.returnValue設為false。
④contextmenu事件屬於鼠標事件,其對象中包含與光標位置有關的所有屬性。
⑤通常使用contextmenu事件來顯示自定義的上下文菜單,而使用onclick事件處理程序隱藏該菜單。
EventUtil.addHandler(window, "load", function(event){
var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "contextmenu", function(event){
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);
var menu = document.getElementById("myMenu");
menu.Style.left = event.clientX + "px";
menu.style.top = event.clientY + "px";
menu.style.visibility = "visible";
});
EventUtil.addHandler(document, "click", fucntion(event){
document.getElementById("myMenu").style.visibility = "hidden";
});
});
4.6.2 卸載前(beforeunload)事件
①beforeunload事件:會在浏覽器卸載頁面之前觸發,可以通過它來取消卸載並繼續使用原有頁面。
②IE和Firefox支持,會彈出詢問用戶是否離開對話框。Safari和Chrome支持,但不妨礙事件繼續,沒有顯示對話框。Opera9.5之前不支持。
EventUtil.addHandler(window, "beforeunload", function(event){
event = EventUtil.getEvent(event);
event.returnValue = "I'm really miss you";
});
4.6.3 鼠標滾輪(mousewheel)和DOMMouseScroll事件
①在鼠標滾輪滾動時觸發
②mousewheel事件為IE、Opera、Chrome、Safari支持,事件對應event中包含鼠標事件的所有標准信息外,還包含一個特殊的wheelEdlta屬性。是120的倍數,向後滾-120倍數。
③9.5之前的版本中,wheelDelta值正負號顛倒。
④Firefox支持DOMMouseScroll事件,滾輪信息存在detail屬性中,前滾為-3倍數,後滾為3倍數。
兼容代碼:
var EventUtil = {
getWheelDlta : function(event){
if(event.wheelDelta){
Return (client.egine.opera && client.egine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta);
}else{
return -event.detail * 40;
}
},
};
4.6.4 DOMContentLoaded事件
①DOMContentLoaded事件在形成完整的DOM樹之後就觸發,不會理圖像、JavaScript文件、CSS文件或其他資源是否已經下載完畢。
EventUtil.addHandler(document,"DOMContentLoaded", function(event){
alert("Content loaded");
});
②對於不支持DOMContentLoad的浏覽器,建議在頁面加載期間設置一時間為0毫秒的超時調用。
setTimeout(function(){
//在此添加事件處理程序
}, 0);
4.6.5 就緒狀態變化(readystatechange)事件
①IE為DOM文檔中某些部分提供了readystatechange事件:提供與文檔或元素的加載狀態有關的信息。
②支持readystatechange事件的每個對象都有一個readyState屬性
□uninitialized(未初始化):對象存在但尚未初始化;
□loading(正在加載):對象正在加載數據;
□loaded(加載完畢):對象加載數據完成;
□interactive(交互):可以操作對象了,但還沒完全加載
□complete(完成):對象已經加載完畢。
③在IE中使用readystatechange近似模擬DOMContentLoaded事件。
EventUtil.addHandler(document, "readystatechange", function(event){
if(document.readyState == "interactive" || document.readyState == "complete"){
eventUtil.removeHandler(document, "readystatechange", arguments.callee);
alert("Content load");
}
});
4.6.6 頁面顯示(pageshow)和頁面隱藏(pagehide)事件
①Firefox和Opera有一個特性,名叫“往返緩存”(back-forward cache,或bfcache)。可以在用戶使用浏覽器的“後退”和“前景”按鈕時加快頁面的轉換速度。
②pageshow事件:在頁面顯示時觸發,無論頁面是否來自bfcache。在重新加載的頁面中,pageshow會在load事件觸發後觸發,而對於bfcache中的頁面,pageshow會在頁面狀態完全恢復的那一刻觸發。
□pageshow事件的event對象包含一個名為persisted的布爾值屬性。如果頁面保存在bfcache中,則只為true,反之則反。
③pagehide事件:事件會在浏覽器卸載頁面的時候觸發,而且是在unload事件之前觸發。
□第一次觸發pagehide時,persisted就會變成true(除非頁面不存在bfcache中)
④指定了onunload事件處理程序的頁面自動排除在bfcache之外。
4.6.7 移動Safari支持的事件
①方向變化(ovientationchange)事件
②觸摸事件
③手勢事件
5.內存和性能
①在JavaScript中,添加到頁面上的事件處理程序數量直接關系到頁面整體運行性能。
□每個函數是對象,都會占用內存;內存中的對象越多,性能越差。
□必須事先指定所有事件處理程序而導致的DOM訪問次數,會延遲整個頁面的交互就緒時間。
5.1 事件委托
①事件委托:解決“事件處理程序過多”問題。
原理:利用事件冒泡,只指定一個事件處理程序,來管理某一類型的所有事件。
var list = document.getElementById("myLinks");
EventUtil.addHandler(list,"click",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "doSomething" : document.title = "I changed the title";
break;
case "goSomewhere" : location.href = "http://www.wrox.com";
break;
case "sayHi" : alert("hi");
break;
}
},false);
②如果可行的話,也可以考慮為document對象添加一個事件處理程序,用以處理頁面上發生的某種特定類型事件。
優點:
□document對象很快就可以訪問,而且可以在頁面生命周期的任何時間點上為它添加事件處理程序(無需等待DOMContentLoad或Load事件)。即只要可單擊的元素呈現在頁面上,就可以立即具備適當的功能。
□在頁面中設置事件處理程序所需的時間更少。只添加一個事件處理程序所需的DOM引用更少,所花的時間也更少。
□整個頁面占用的內存空間更少,能提升整體性能。
③使用范圍
□適合采用事件委托技術的事件包括click、mousedown、mouseup、keydown、keyup和keypress。
□雖然mouseover和mouseout事件也冒泡,但要適當處理他們並不容易,而且經常需要計算元素的位置(因當鼠標從一個元素移動到其子節點時或者鼠標移出該元素時,就會觸發mouseout事件)
5.2 移除事件處理程序
①浏覽器頁面代碼與JavaScript代碼之間建立的鏈接越多,執行越慢。可用事件委托技術,限制建立的鏈接數量。在不需要的時候移除事件處理程序。
②內存中留有過時不用的“空事件處理程序”(dangling event handler)也是造成web應用程序內存與性能問題的主要原因。
1)第一種情況:從文檔中移除帶有事件處理程序的元素時。如removeChild()和replaceChild()方法,更多是發生在使用innerHTML替換頁面中某一部分的時候。
□手動解除這些“空事件處理程序”,釋放內存。
var btn = document.getElementById("myBtn");
btn.onclick = function(){
//先執行某些操作
btn.onclick = null; //移除事件處理程序
document.getElementById("myDiv").innerHTML = "prossing";
};
2)另一種情況:卸載頁面的時候。若沒有清理干淨會滯留內存。
□在卸載之前,先通過onunload事件處理程序移除所有事件處理程序。
6.模擬事件
可以使用JavaScript在任意時刻來觸發特定的事件,而此時的事件就如同浏覽器創建的事件一樣。即該冒泡會冒泡,且照樣導致浏覽器執行已經制定處理它們的事件處理程序。
6.1 DOM中的事件模擬
■可以在docuemnt對象上使用createEvent()方法創建對象。這個方法接受一個參數,即表示創建事件類型的字符串,如下:
□UIEvents:一般化的UI事件。鼠標事件和鍵盤事件都繼承自UI事件。
□MouseEvents:一般化的鼠標事件。
□MutationEvents:一般化的DOM變動事件。
□HTMLEvents:一般化的HTML事件。
■各種類型創建的event對象,都有一個特殊的方法,為它傳入適當的數據可以初始化該event對象。
■觸發事件:調用dispatchEvent()方法,傳入要觸發事件的event對象。
6.1.1 模擬鼠標事件
①創建新的鼠標事件對象並為其指定必要的信息,就可以模擬鼠標事件。創建鼠標事件的對象方法是createEvent(),傳入字符串"MouseEvents"。返回的對象有一個名為initMouseEvent()方法,用於指定與該鼠標事件有關的信息。
initMouseEvent()方法15個參數:
□type(字符串):表示要觸發的事件類型名,例如“click”。
□bubbles(布爾值):表示事件是否應該冒泡。
□cancelable(布爾值):表示事件是否可以取消。
□view(AbstractView):與事件關聯的視圖。幾乎總設為document.defaultView
□detail(整數):與事件有關的詳細信息。通常設為0
□screenX(整數):事件相對於屏幕的X坐標。
□screenY
□clientX(整數):事件相對於視口的X坐標。
□clientY
□ctrlKey(布爾值):表示是否按下了Ctrl鍵。默認為false
□altKeyu
□shiftKey
□metaKey
□button(整數):表示按下了哪一個鼠標鍵。默認0
□relatedTarget(對象):表示與事件相關的對象。這參數只在模擬mouseover或mouseout時使用。
var btn = document.getElementById("myBtn");
//創建事件對象
var event = document.creeateEvent("MouseEvents");
//初始化事件對象
event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);
//觸發事件
btn.dispatchEvent(event);
6.1.2 模擬鍵盤事件
①Firefox中調用createEvent()並傳入"keyEvents"就可以創建一個鍵盤事件。返回的事件對象會包含一個initKeyEvent()方法。
②在其他浏覽器中,則需要創建一個通用的事件,然後再向事件對象添加鍵盤事件特有的信息。
var textbox = document.getElementById("myTextbox");
//創建事件對象
var event = document.createEvent("Events");
//初始化事件對象
event.initEvent(type,bubbles,cancelable);
event.view = document.defaultView;
event.altKey = false;
event.ctrlKey = false;
event.shiftKey = false;
event.metaKey = false;
event.keyCode = false;
event.charCode = false;
//觸發事件
textbox.dispatchEvent(event);
6.1.3 模擬其他事件(變動事件和HTML事件)
6.2 IE中的事件模擬
IE中思路與DOM相同,其中的區別:
□IE使用document.createEventObject()方法創建對象。此法不接受參數,僅返回一個通用event對象。必須手工為此對象添加屬性。
□觸發事件在目標上調用fireEvent()方法。兩個參數:事件處理程序名和event對象。在調用fireEvent()方法時,會自動為event對象添加srcElement和type屬性。
第十三章 表單腳本
1.表單
①JavaScript中表單<form>對應HTMLFormElement類型。HTMLFormElement繼承了HTMLElement,因而與其它HTML元素具有相同的默認屬性。也有其獨有屬性和方法:
□acceptCharset:服務器能夠處理的字符集;等價HTML中的accept-charset特性。
□action:接受請求的URL;等於HTML中的action特性。
□elements:表單中所有控件的集合(HTMLCollection)。
□enctype:請求的編碼類型;等價於HTML中的enctype特性。
□length:表單中控件的數量。
□method:要發送的HTTP請求類型,通常是“get”或“post”;等價於HTML的method特性。
□name:表單名稱;等價於HTML的name特性。
□reset():將所有表單域重置為默認值。
□submit():提交表單。
□target:用於發送請求和接收響應的窗口名稱;等價於HTML的target特性。
②獲取表單
var form = document.getElementById("form1");
var firstForm = document.forms[0];
var myForm = document.forms["form2"];
1.1 提交表單
①提交表單的三種方法:
□通用按鈕:<input type="submit" value="submit Form"/>
□自定義按鈕:<button type="submit">Submit Form</button>
□圖像按鈕:<input type="image" src="graphic.gif"/>
②在提交表單時,浏覽器會將請求發送給服務器之前觸發submit事件。這樣就有機會驗證表單數據,並據以決定是否允許表單提交。
var form = document.getElementById("myForm");
EventUtil.addHandler(form,"submit",function(event){
//取得事件對象
event = EventUtil.getEvent(event);
//阻止默認事件
EventUtil.preventDefault(event);
});
③提交表單的最大問題是重復提交表單。解決辦法:在第一次提交表單後就禁用提交按鈕。
④在JavaScript中,可以以編程方式提交表單。
var form = document.getElementById("myForm");
//提交表單
form.submit(); //此方法提交表單不會觸發submit事件
1.2 重置表單
①重置表單方式
□通用按鈕:<input type="reset" value="Reset Form"/>
□自定義按鈕:<button type="reset">Rest Form</button>
②用戶單擊重置按鈕重置表單是,會觸發reset事件,利用這個機會可在必要時取消重置操作。
③可用JavaScript重置表單:form.reset();與調用submit()方法不同,調用reset()方法會想單擊重置按鈕一樣觸發reset事件。
1.3表單字段
①訪問表單字段方法:
□使用原生DOM方法。
□通過表單的elements屬性,該屬性是表單中所有元素的集合。
◇表單字段按標記順序保存在elements中。
◇可以按照位置和name特性訪問它們。
◇如果多個表單控件都使用一個name特性,則返回一個NodeList。
var form = document.getElementById("form1");
//取得表單中的第一個字段
var field1 = form.elements[0];
//取得名為textbox1的字段
var field2 = form.elements["textbox1"];
//取得表單中包含的字段的數量
var fieldCount = form.elements.length;
1.3.1 共有的表單字段屬性
①表單字段共有的屬性和方法如下:
□disabled:布爾值,表示當前字段是否被禁用。
□form:指向當前字段所屬表單的指針,只讀。
□name:當前字段的名稱。
□readOnly:布爾值,表示當前字段是否只讀。
□tabIndex:表示當前字段的切換(tab)序號。
□type:當前字段的類型,如:“checkbox”、“radio”等等。
□value:當前字段將被提交給服務器的值。
②不能用click事件處理submit事件,因不知道在submit前觸發click還是submit後觸發click。
1.3.2 共有的表單字段方法
□focus()方法:將浏覽器的焦點設置到表單字段。
□blur()方法:從元素中移走焦點。
1.3.3 共有的表單字段事件
除了支持鼠標事件、鍵盤、變動和HTML事件外,所以表單字段支持下列3個事件:
□blur:當前字段失去焦點時觸發。
□change:對於<input>和<textarea>元素,他們失去焦點切value值改變時觸發;對於<select>元素,在其選項改變時觸發。
□focus:當前字段獲得焦點時觸發。
2.文本框腳本
①在HTML中兩種方法表現文本框
□使用<input>元素的單行文本框
◇顯示25個字符,輸入不超過50個字符。size="25" maxlength="50"
□<textarea>元素,多行文本框
◇25行,5列。rows="25" cols="5"
②設置文本框的值
□使用value屬性讀取或設置文本框的值,不建議使用DOM方法。
□使用DOM方法:setAttribute()設置value特性或修改<textarea>元素第一個子節點這樣對value值的修改不一定反映到DOM中。
2.1 選擇文本
①<input>單行文本和<textarea>多行文本都支持select()方法,這個方法用於選擇文本框中所有文本。
EventUtil.addHandler(textbox, "focus", function(){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
2.1.1 選擇(select)事件
select事件觸發的情況復雜,要想編寫跨浏覽器代碼,必須手工取得對事件目標的引用:
var textbox = document.forms[0].elements["textbox1"];
EventUtil.addHandler(textbox,"select",function(event){
var target = document.forms[0].elements["textbox1"];
alert("text selected");
});
2.1.2 取得選擇的文本
□文本框的兩個屬性:selectionStart和selectionEnd。基於0的數值,表示所選文本范圍。FF、Safari、Chrome、Opera支持。
□IE有一個document.select對象,其中保存用戶整個文檔范圍內選擇的文本信息。與select事件一起,可假定為文本內容。取值前須創建一個范圍。
function getSelectedText(textbox){
if(document.selection){
return document.selection.createRange().text;
}else{
return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd);
}
}
2.1.3 選擇部分文本
□setSelectionRange()方法。接受兩個參數:要選擇的第一個字符的索引和要選擇的最後一個字符之後的字符索引。FF、Chrome、Safari、Opera支持。
□IE為文本框提供了createTextRange()方法,要選擇文本框中的部分文本,必須首先使用這個方法創建一個范圍,並將其放在恰當位置上。再使用moveStart()和moveEnd()這兩個方法將范圍移動位置。
□兼容代碼
function selectText(textbox,strtIndex,stopIndex){
if(textbox.setSelectionRange){
textbox.setSelectionRange(startIndex,stopIndex);
}else if(textbox.createTextRange){
var range = textbox.createTextRange();
range.collapse(true);
range.moveStart("character",startIndex);
range.moveEnd("charater",stopIndex-startIndex);
range.select();
}
Textbox.focus();
}
2.2.1 過濾輸入
例為屏蔽非數字值,而不屏蔽ctrl組合鍵
EventUtil.addHandler(textbox,"keypress",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
var charCode = EventUtil.getCharcode(event);
if(!/\d/.test(String.fromCharCode(charCode))&&charCode>9&&!event.ctrlkey){
EventUtil.preventDefault(event);
}
});
2.2.2 操作剪貼板
①6個剪貼板事件:
□beforecopy:在發生復制操作前觸發;
□copy:在發生復制操作時觸發
□beforecut:在發生剪切操作時觸發。
□cut:在發生剪切操作時觸發
□beforepaste:在發生粘貼操作前觸發
□paste:在發生粘貼操作時觸發
②訪問剪貼板中數據,可使用clipboaredData對象,有3個方法:
getDate()、setDate()和clearData()
兼容方法:
var EventUtil = {
getClipboardText : function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
},
setClipboardText : function(event, value){
if(event.clipboardData){
return event.clipboardData.setData("text/pain",value);
}else if(window.clipboardData){
return window.clipboardData.setData("text",value);
}
},
};
3.選擇框腳本
①選擇框是通過<select>和<option>元素創建的。HTMLSelectElement類型還提供了下列屬性和方法:
□add(newOption, relOption):向空間按中插入新元素,其位置在指定項relOption之前
□multiple:布爾值,表示是否允許多項選擇;等價於HTML中的multiple特性。
□options:控件中所有<option>元素的HTMLCOllection。
□remove(index):移除給定位置選項。
□selectedIndex:基於0的選中項的索引,如果沒有選中項,則值為-1.對於支持多選的控件,只保存選項中第一項的索引。
□size:選擇框中可見的行數;等價於HTML中的size特性
□type:"select-one"或"select-multiple",取決於HTML代碼中有沒multiple特性。
□value:取決於當前選中項。
②DOM中,每個<option>元素都有一個HTMLOptionElement對象表示。其對象添加以下屬性:
□index:當前選項在options集合中的索引
□label:當前選項的標簽;等價於HTML中的label特性
□selected:布爾值,表示當前選項是否被選中。設true可選中。
□text:選項的文本
□value:選項的值(等價於HTML中的value特性)
3.1 選擇選項
□對於只允許一項的選擇框,使用選擇框的selectedIndex屬性。
var selectedOption = selectbox.options[selectbox.selectedIndex];
□對於多選的選擇框,遍歷檢查其selected屬性。
3.2 添加選項
①DOM方法:
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("Option text");
newOption.setAttribute("value","Option value");
selectbox.appendChild(newOption);
②Option構造函數,接受兩個參數:文本(text)和值(value);第二個可選。(IE不可用)
Var newOption = new Option("Option text","Option value");
Selectbox.appendChild(newOption); //在IE中有問題
③使用選擇框的add()方法,接受兩個參數:要添加的新選項和將位於新選項之後的選項。
Var newOption = new Option("Option text", "Option value");
Selectbox.add(newOption, undefined); //最佳方案
3.3 移除選項
①可使用DOM的removeChild()方法,為其傳入要移除的項。
selectbox.removeChild(selectbox.option[0]);
②使用選擇框的remove()方法。接受一個參數,即要移除項的索引。
selectbox.remove(0); //移除第一個選項
③將相應項設為null
3.4 移動和重排選項
①使用appendChild()方法,講一個選擇框中選項移到另一個選擇框。
②使用insertBefore()實現重排
4.表單序列化
①浏覽器發數據至服務器方式:
□對表單字段的名稱和值進行URL編碼,使用和號(&)分隔。
□不發送禁用的表單字段
□只發送勾選的復選框和單選按鈕
□不發送type為“reset”和“button”的按鈕。
□多選選擇框中的每個選中值單獨一個條目。
□在單擊提交按鈕表單的情況下,也會發送提交按鈕;否則,不發送提交按鈕。也包括type為"image"的<input>元素。
□<select>元素的值,就是選中<option>元素的value特性的值。如果<option>元素沒有value特性,則是<option> 元素的文本值。
②表單序列化代碼:
function serialize(form){
var parts = new Array();
var field = null;
for(var i = 0, len = form.elements.length; i < len; i++){
field = form.elements[i];
switch(field.type){
case "select-one" :
case "select-multiple" :
for(var j=0, optLen = field.options.length; j<optLen; j++){
var option = field.options[j];
if(option.selected){
var optValue=" ";
if(potion.hasAttribue){
optValue = (option.hasAttribute("value") ? Option.value : option.text);
}else{
optValue = (option.attributes["value"].specified ? Option.value : option.text);
}
parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue));
}
case undefined : //字段集
case "file" : //文件輸入
case "submit" : //提交按鈕
case "reset" : //自定義按鈕
Break;
case "radio" : //單選按鈕
case "checkbox" : //復選框
If(!field.checked){break;}
default :
parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.name));
return parts.join("&");
}
}
}
5.富文本編輯(略)

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved