事件:交互體驗的核心瘸爽,div.onclick = function(){};// "="號左邊就是事件了,右邊是觸發(fā)事件執(zhí)行的函數(shù);所謂的綁定事件,并非是創(chuàng)建事件,dom元素本來就有事件,我們只是綁定了執(zhí)行函數(shù)而已浩考;【當頁面全部加載完成后只怎,程序執(zhí)行從同步腳本執(zhí)行階段,轉化為事件驅動階段】
1、綁定事件處理函數(shù)的三種方式:
(1).div.onclick = function(){ this.style.backgroundColor='red';}?等同于在行內樣式中添加仲翎,? ? ? ? ? ? <div style="width:100px"? onclick="console.log('a')"></div>//行內樣式中直接寫函數(shù)執(zhí)行語句,不需要寫function(){};//以上這種方式被稱為“句柄綁定”的方式;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -------->>>其兼容性很好,缺點:一個對象的一個事件只能綁定一個處理函數(shù)(綁定多個函數(shù)會出現(xiàn)覆蓋現(xiàn)象);
(2).div.addEventListener(事件類型廓脆、處理函數(shù)、false)颅停;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? div.addEventListener('click',function(){},false);其可以給一個對象的一個事件綁定多個處理函數(shù),并且按照綁定的順序執(zhí)行;IE9以下不兼容胳泉;
[1].下式綁定的函數(shù)是引用值凤瘦,顯然點擊觸發(fā)的是兩個不同的函數(shù),結果:點擊一次輸出兩個a案铺;
[2].?下式綁定的函數(shù)引用蔬芥,其是同一個函數(shù),結果:點擊一次輸出一個b;
(3).IE9獨有:div.attachEvent('on'+事件類型,處理函數(shù))笔诵;一個對象的一個事件綁定多個處理函數(shù),?但其不同于div.addEventListener();? 即使是[2].式其也可以執(zhí)行多次返吻,結構很松散;
事件中的this指向問題:
------>>>封裝兼容性的綁定函數(shù)方法:
解除事件綁定:使用場景還是蠻廣的乎婿,有的事件綁定只需要進行一次就OK测僵,綁定后需要解除綁定;(封裝解除事件綁定的函數(shù)應用場景不大)
事件中形成的閉包現(xiàn)象:(開發(fā)中經(jīng)常遇到谢翎,但不容易想到)
例:點擊每個li捍靠,輸出序號;
[注:事件一旦出現(xiàn)在循環(huán)當中森逮,重點考慮函數(shù)與for循環(huán)是否形成閉包榨婆,若出現(xiàn)閉包,使用立即執(zhí)行函數(shù)解決]
2褒侧、事件處理模型:冒泡良风、捕獲;[事件處理方式璃搜,其也是特殊現(xiàn)象] 【聚焦點:結構上嵌套拖吼,同一事件類型】
(1).事件冒泡:結構上(非視覺上)嵌套關系的元素,會存在事件冒泡这吻,同一事件,子元素冒泡向父元素篙议;(自底向上) 【每個瀏覽器都支持】三種事件綁定處理函數(shù)都OK唾糯;
(2).事件捕獲:結構上(非視覺上)嵌套關系的元素,會存在事件捕獲的功能鬼贱,即同一事件移怯,自父元素捕獲至子元素(事件源對象);(自頂向下) 【早期只有谷歌支持这难,目前火狐和opera高版本支持低版本沒有(高版本的幾乎都涉及谷歌的webkit內核)舟误,IE不支持捕獲事件類型】div.addEventListener('click',function(){}, true);? 只要把第三個參數(shù)由false變?yōu)閠rue即可;
【其也可認為是捕獲:div.setCapture();//僅在IE瀏覽器好使姻乓,dom元素會將頁面中所有的事件硬捕獲到自己身上嵌溢,常與div.releaseCapture();配套使用//捕獲后需要釋放,因為其對其他事件有壞處】
(3).先捕獲蹋岩,后冒泡:嵌套關系的父子元素才談這兩個現(xiàn)象赖草,一個對象一個事件類型綁定的一個執(zhí)行函數(shù)只能遵循一個事件處理模型,要不冒泡剪个、要不捕獲秧骑;但一個對象一個事件可以綁定多個執(zhí)行函數(shù),若是綁定兩個執(zhí)行函數(shù),一個冒泡乎折、一個捕獲绒疗,則先發(fā)生捕獲、后冒泡骂澄;涉及多個處理函數(shù)忌堂,只能用第二種了;
順序:點擊黃色方塊-->>紅色方塊捕獲-->>綠色方塊捕獲-->>黃色方塊執(zhí)行-->>黃色方塊執(zhí)行-->>冒泡向綠色方塊-->>冒泡向紅色方塊酗洒;(黃色方塊執(zhí)行順序就是書寫的事件執(zhí)行順序)
補充:并非所有事件都會冒泡:focus,blur,change,submit,reset,select等事件不冒泡士修;【冒泡/捕獲聚焦點是同一事件類型,多為點擊事件類型】
------->>>>>取消冒泡:冒泡是事件處理方式樱衷,有時候不需要這類現(xiàn)象的發(fā)生棋嘲;應用場景:document是所有dom元素的父級,若是給document綁定事件矩桂,其他dom元素綁定同類事件沸移,則會發(fā)生冒泡,必須取消冒泡的影響侄榴;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [1].event.stopPropagation();// w3c標準,ie9以下不兼容雹锣;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [2].IE9以下:event.cancelBubble = true;//目前chrome也已經(jīng)實現(xiàn)
----->>>>>封裝兼容性函數(shù):【圖示這種if條件判斷語句不能使用三目運算符,三目聚焦點是返回值癞蚕,var a; if(){ a = xxx}else{ a = xxx},這種方式可以使用三目】
3蕊爵、阻止事件默認行為:(應用場景很廣泛)[有默認行為的事件類型并不多]? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [手機、電腦桦山、平板等系統(tǒng)內部自帶很多默認事件攒射,例如鼠標右擊彈出菜單便是一個默認事件,可以阻止其的發(fā)生恒水;常見的默認事件:表單提交会放、a標簽跳轉、右鍵菜單等等]
(1).return false;// 只能用于事件句柄中div.onclick;?其他事件綁定函數(shù)中不能使用钉凌;document.oncontextmenu = function(){ console.log('a');? ?ruturn false;}
(2).event.preventDefault();// w3c標準咧最,IE9以下不兼容;
(3).event.returnValue = false;// IE御雕;
封裝兼容性函數(shù):(1)return false;//不好實現(xiàn),?同理return f(n);函數(shù)也不好實現(xiàn)矢沿;封裝函數(shù)足夠用了
補充: a標簽有默認行為:<a href="#"></a>跳轉到“#”并刷新頁面; // 如果在底部進行a標簽的跳轉,頁面會彈回頂部饮笛,開發(fā)中我們常使用a標簽當作按鈕使用咨察,需要阻止默認行為;? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[1].常規(guī):event.preventDefault();或者使用兼容性封裝函數(shù)也OK福青;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[2].<a href="javascript:void()">demo</a>;使用協(xié)議協(xié)定符摄狱;<a? href="javascript:alert('a')"></a> href=“js代碼”脓诡,點擊便會去執(zhí)行js代碼;同樣使用<a?href="javascript: void()">demo</a>,void()等同于是返回值媒役,void(false) ===>>> return false;
4祝谚、事件對象event:觸發(fā)事件后的所有信息都封裝在event對象中(反映當前事件發(fā)生時的一系列狀態(tài)和信息)梦皮,瀏覽器默認把event事件對象傳給形參蜓氨,IE瀏覽器其會把event事件對象傳window.event上疲酌,兼容性寫法:div.onclick = function(e){var event = e || window.event}
[event.clientX/clientY:?事件觸發(fā)時鼠標的x,y坐標,等同于pageX/pageY;? clientWidth/Height可視區(qū)]
【1.盡量使用形參崇堰;2.后續(xù)event事件對象的使用可以巧妙解決很多問題】
5、事件源對象:確認是誰觸發(fā)的事件(由于有事件冒泡模型启摄,嵌套元素都可以觸發(fā)事件執(zhí)行函數(shù)凌外,但并不清楚是那個元素觸發(fā))蹦玫;根據(jù)event事件對象來確認事件源對象啊片,event.target;火狐只有這個只锻,event.srcElement IE只有這個,chrome兩者都有紫谷,兼容性寫法:
6齐饮、事件委托(事件代理):利用事件冒泡、事件源對象進行處理笤昨;(巧妙使用祖驱,節(jié)省性能)
例:給每個li綁定事件,點擊觸發(fā)后輸出標簽內容瞒窒;
常規(guī)寫法:雖然可以實現(xiàn)功能捺僻,但若是動態(tài)增加<li>個數(shù)、<li>總數(shù)過多根竿,性能和靈活性便會變差陵像;使用“事件委托”,綁定<ul>,利用事件冒泡寇壳、事件源對象進行處理,提高性能和靈活性妻怎;
優(yōu)化版:利用事件冒泡,點擊li, li冒泡向ul;ul執(zhí)行函數(shù)會執(zhí)行壳炎;?利用事件源對象,得到最終點擊的是誰逼侦;輸出事件源對象的InnerHTML即可匿辩;
7、事件分類:以下都是常用事件類型榛丢;
(1).鼠標事件:click;dblclick;contextmenu;?mousemove; mousedown/mouseup; mouseover;/mouseout; mouseenter;/mouseleave;
[1].onclick = onmousedown + onmouseup;(完成按下+彈起才是完整的點擊事件)
[2].DOM3標準規(guī)定:click事件只能監(jiān)聽左鍵铲球,只能通過mousedown和mouseup來判斷鼠標鍵;(event事件對象中的button屬性值:0:左; 1:滾輪; 2:右)(chick事件右鍵為出菜單contextmenu;)
[3].鼠標拖拽事件:(拖著物塊運動)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 【解決bug使用的是在document文檔上觸發(fā)事件晰赞,還有一種解決方案稼病,也可稱其為捕獲(不是很嚴格)选侨,div.setCapture();//僅在IE瀏覽器好使,dom元素會將頁面中所有的事件硬捕獲到自己身上然走,常與div.releaseCapture();配套使用//捕獲后需要釋放援制,因為其對其他事件有壞處】
[4].解決mousedown和click的沖突:(解決其是點擊or拖拽)例:a標簽制作的物塊,如何判斷點擊跳轉還是拖拽其移動芍瑞?(根據(jù)生物行為特征時間差)
補充:[1].click,dblclick,多次點擊計算總點擊次數(shù)除以1/2來確認觸發(fā)事件頻次晨仑;? ? ? ? ? ? ? ? ? ? [2].contextmenu:應用場景最多的是阻止右鍵出菜單事件;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [3].mousemove往往與mousedown/up配套使用;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [4].mouseenter/mouseleave:鼠標移入觸發(fā)拆檬,其不會發(fā)生冒泡洪己;mouseover/mouseout:鼠標移入觸發(fā),其會發(fā)生冒泡竟贯;(一般使用前者)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [5].css中的hover底層是用js實現(xiàn)的答捕,html中的form表單提交功能底層用js中submit事件實現(xiàn),相比于js代碼直接去操作澄耍,html/css是直接由底層引擎實現(xiàn)噪珊,速度更快,hover肯定比js實現(xiàn)的更快齐莲;? ? ? ? ? ? [6].移動端使用的是click;/touchmove/touchstart;/touchend;
(2).鍵盤事件:keydown keypress keyup;
[1].觸發(fā)順序:keydown -->> keypress -->>keyup;?相比于鼠標事件痢站,鍵盤事件onkeydown按下會連續(xù)觸發(fā),直到onkeyup选酗;(根據(jù)應用場景設計阵难,游戲設計中綁定keydown事件)
[2].keydown和keypress區(qū)別:只有按下便會觸發(fā)兩個事件類型,keydown>keypress;
區(qū)別:keydown可以檢測所有鍵盤類按鍵芒填,除了fn(輔助按鍵);keypress只能檢測字符類按鍵(ASCII碼表中的按鍵)呜叫;兩者觸發(fā)事件的event對象有charCode();可返回ASCII碼,keydown中event.charCode;//都為0殿衰;控制類按鍵(上/下/左/右,ctrl/shift/alt)沒有keypress;因為沒有ASCII碼對應
keypress返回ASCII碼朱庆,可轉換為相應的字符,有一定的應用場景闷祥;String.fromCharCode();//String靜態(tài)類的靜態(tài)方法娱颊,參數(shù)傳入ASCII碼,返回相應字符凯砍;shift+a; alt+a;//也OK箱硕;
鍵盤類事件event事件對象中witch屬性表示的是鍵盤108個鍵中的鍵號,其和ASCII碼沒關系悟衩;
(3).文本操作事件:input change focus blur;
[有bug,當輸入"請輸入用戶名"時剧罩,焦點離開沒問題,焦點再聚焦到輸入框時座泳,內容便會清空惠昔;大廠也有此bug]
(4).窗體操作類window上的事件:scroll? load;
window.onscroll = function(){};
window.onload = function(){};//一般不要把主程序放到函數(shù)體幕与,window.onload是指網(wǎng)頁內容全部加載完成,不同于文檔加載完成舰罚,網(wǎng)速不好的情況下1k未加載成功都會影響后續(xù)的操作纽门;當然也有應用場景:廣告顯示(頁面全部加載完成后,觸發(fā)廣告部分);
window.onload=function(){};?整個頁面加載完成后執(zhí)行营罢;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? $(document).ready(function(){ });? jquery中這種方式表示dom解析完就執(zhí)行赏陵;document.addEventListener('DOMContentLoaded',function(){},false);? dom解析完成后就執(zhí)行;[此事件沒有句柄的方式饲漾,只能使用addEventListener();]