《jQuery零基礎入門》系列博文是在廖雪峯老師的博文基礎上,可能補充了我的的理解和平常遇到的點,用個人理解表述出來,主幹出處來自廖雪峯老師的技術分享。javascript
咱們在《零基礎入門JavaScript》的課程中,就重點講過JavaScript的事件。由於JavaScript在瀏覽器中以單線程模式運行,頁面加載後,一旦頁面上全部的JavaScript代碼被執行完後,就只能依賴觸發事件來執行JavaScript代碼。html
瀏覽器在接收到用戶的鼠標或鍵盤輸入後,會自動在對應的DOM節點上觸發相應的事件。若是該節點已經綁定了對應的JavaScript處理函數,該函數就會自動調用。因爲不一樣的瀏覽器綁定事件的代碼都不太同樣,因此用jQuery來寫代碼,就屏蔽了不一樣瀏覽器的差別,咱們老是編寫相同的代碼。java
舉個例子,假設要在用戶點擊了超連接時彈出提示框,咱們用jQuery這樣綁定一個click
事件:瀏覽器
/* HTML: * * <a id="test-link" href="#0">點我試試</a> * */ // 獲取超連接的jQuery對象: var a = $('#test-link'); a.on('click', function () { alert('Hello!'); });
on
方法用來綁定一個事件,咱們須要傳入事件名稱和對應的處理函數。安全
另外一種更簡化的寫法是直接調用click()
方法:函數
a.click(function () { alert('Hello!'); });
二者徹底等價。咱們一般用後面的寫法。spa
jQuery可以綁定的事件主要包括:線程
鍵盤事件僅做用在當前焦點的DOM上,一般是<input>
和<textarea>
。code
<input>
、<select>
或<textarea>
的內容改變時觸發;<form>
提交時觸發;其中,ready
僅做用於document
對象。因爲ready
事件在DOM完成初始化後觸發,且只觸發一次,因此很是適合用來寫其餘的初始化代碼。假設咱們想給一個<form>
表單綁定submit
事件,下面的代碼沒有預期的效果:orm
<html> <head> <script> // 代碼有誤: $('#testForm).on('submit', function () { alert('submit!'); }); </script> </head> <body> <form id="testForm"> ... </form> </body>
由於JavaScript在此執行的時候,<form>
還沒有載入瀏覽器,因此$('#testForm)
返回[]
,並無綁定事件到任何DOM上。
因此咱們本身的初始化代碼必須放到document
對象的ready
事件中,保證DOM已完成初始化:
<html> <head> <script> $(document).on('ready', function () { $('#testForm).on('submit', function () { alert('submit!'); }); }); </script> </head> <body> <form id="testForm"> ... </form> </body>
這樣寫就沒有問題了。由於相關代碼會在DOM樹初始化後再執行。
因爲ready
事件使用很是廣泛,因此能夠這樣簡化:
$(document).ready(function () { // on('submit', function)也能夠簡化: $('#testForm).submit(function () { alert('submit!'); }); });
甚至還能夠再簡化爲:
$(function () { // init... });
上面的這種寫法最爲常見。若是你遇到$(function () {...})
的形式,牢記這是document
對象的ready
事件處理函數。
徹底能夠反覆綁定事件處理函數,它們會依次執行:
$(function () { console.log('init A...'); }); $(function () { console.log('init B...'); }); $(function () { console.log('init C...'); });
有些事件,如mousemove
和keypress
,咱們須要獲取鼠標位置和按鍵的值,不然監聽這些事件就沒什麼意義了。全部事件都會傳入Event
對象做爲參數,能夠從Event
對象上獲取到更多的信息:
$(function () { $('#testMouseMoveDiv').mousemove(function (e) { $('#testMouseMoveSpan').text('pageX = ' + e.pageX + ', pageY = ' + e.pageY); }); });
一個已被綁定的事件能夠解除綁定,經過off('click', function)
實現:
function hello() { alert('hello!'); } a.click(hello); // 綁定事件 // 10秒鐘後解除綁定: setTimeout(function () { a.off('click', hello); }, 10000);
須要特別注意的是,下面這種寫法是無效的:
// 綁定事件: a.click(function () { alert('hello!'); }); // 解除綁定: a.off('click', function () { alert('hello!'); });
這是由於兩個匿名函數雖然長得如出一轍,可是它們是兩個不一樣的函數對象,off('click', function () {...})
沒法移除已綁定的第一個匿名函數。
爲了實現移除效果,可使用off('click')
一次性移除已綁定的click
事件的全部處理函數。
同理,無參數調用off()
一次性移除已綁定的全部類型的事件處理函數。
一個須要注意的問題是,事件的觸發老是由用戶操做引起的。例如,咱們監控文本框的內容改動:
var input = $('#test-input'); input.change(function () { console.log('changed...'); });
當用戶在文本框中輸入時,就會觸發change
事件。可是,若是用JavaScript代碼去改動文本框的值,將不會觸發change
事件:
var input = $('#test-input'); input.val('change it!'); // 沒法觸發change事件
有些時候,咱們但願用代碼觸發change
事件,能夠直接調用無參數的change()
方法來觸發該事件:
var input = $('#test-input'); input.val('change it!'); input.change(); // 觸發change事件
input.change()
至關於input.trigger('change')
,它是trigger()
方法的簡寫。
爲何咱們但願手動觸發一個事件呢?若是不這麼作,不少時候,咱們就得寫兩份如出一轍的代碼。
在瀏覽器中,有些JavaScript代碼只有在用戶觸發下才能執行,例如,window.open()
函數:
// 沒法彈出新窗口,將被瀏覽器屏蔽: $(function () { window.open('/'); });
這些「敏感代碼」只能由用戶操做來觸發:
var button1 = $('#testPopupButton1'); var button2 = $('#testPopupButton2'); function popupTestWindow() { window.open('/'); } button1.click(function () { popupTestWindow(); }); button2.click(function () { // 不馬上執行popupTestWindow(),100毫秒後執行: setTimeout(popupTestWindow, 100); });
當用戶點擊button1
時,click
事件被觸發,因爲popupTestWindow()
在click
事件處理函數內執行,這是瀏覽器容許的,而button2
的click
事件並未馬上執行popupTestWindow()
,延遲執行的popupTestWindow()
將被瀏覽器攔截。