事件

由於JavaScript在瀏覽器中以單線程模式運行,頁面加載後,一旦頁面上全部的JavaScript代碼被執行完後,就只能依賴觸發事件來執行JavaScript代碼。javascript

瀏覽器在接收到用戶的鼠標或鍵盤輸入後,會自動在對應的DOM節點上觸發相應的事件。若是該節點已經綁定了對應的JavaScript處理函數,該函數就會自動調用。html

因爲不一樣的瀏覽器綁定事件的代碼都不太同樣,因此用jQuery來寫代碼,就屏蔽了不一樣瀏覽器的差別,咱們老是編寫相同的代碼。java

舉個例子,假設要在用戶點擊了超連接時彈出提示框,咱們用jQuery這樣綁定一個click事件:jquery

 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery</title>
<script src="/static/js/jquery-3.2.1.min.js"></script>
</head>
<body>
<a id="test-link" href="#0">點我</a>
<script>
'use strict';
//獲取超連接的jQuery對象
var a = $('#test-link');
a.on('click', function(){
  alert('Hello ^-^');
});
</script>
</body>
</html>

 on方法用來綁定一個事件,咱們須要傳入事件名稱和對應的處理函數。瀏覽器

另外一種更簡化的寫法是直接調用click()方法:安全

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery</title>
<script src="/static/js/jquery-3.2.1.min.js"></script>
</head>
<body>
<a id="test-link" href="#0">點我</a>
<script>
'use strict';
//獲取超連接的jQuery對象
var a = $('#test-link');
a.click(function(){
   alert('Hello ^-^');
});
</script>
</body>
</html>

 

這二者徹底等價,可是咱們一般使用第二種寫法。函數

鼠標事件

click: 鼠標單擊時觸發; dblclick:鼠標雙擊時觸發; mouseenter:鼠標進入時觸發; mouseleave:鼠標移出時觸發; mousemove:鼠標在DOM內部移動時觸發; hover:鼠標進入和退出時觸發兩個函數,至關於mouseenter加上mouseleave。spa

鍵盤事件

鍵盤事件僅做用在當前焦點的DOM上,一般是<input><textarea>線程

keydown:鍵盤按下時觸發; keyup:鍵盤松開時觸發; keypress:按一次鍵後觸發。code

其餘事件

focus:當DOM得到焦點時觸發; blur:當DOM失去焦點時觸發; change:當<input><select><textarea>的內容改變時觸發; submit:當<form>提交時觸發; ready:當頁面被載入而且DOM樹完成初始化後觸發。

其中,ready僅做用於document對象。因爲ready事件在DOM完成初始化後觸發,且只觸發一次,因此很是適合用來寫其餘的初始化代碼。假設咱們想給一個<form>表單綁定submit事件,下面的代碼沒有預期的效果:

<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...');
});

 事件參數

有些事件,如mousemovekeypress,咱們須要獲取鼠標位置和按鍵的值,不然監聽這些事件就沒什麼意義了。全部事件都會傳入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...');
});

 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery</title>
<script src="/static/js/jquery-3.2.1.min.js"></script>
</head>
<body>
<input id="test-input" type="TEXT" name="change" value="change">
<input type="SUBMIT" value="submit">
<script>
var input=$('#test-input');
input.change(function(){
  console.log('changed.................');
});
</script>
</body>
</html>

 

結果:

點擊提交按鈕後,Console控制檯就會打出函數體的內容。

可是若是用JavaScript代碼去改動文本框的值,將不會觸發change事件:

var input = $('#test-input');
input.val('change it!'); // 沒法觸發change事件

 

 有些時候,咱們但願用代碼觸發change事件,能夠直接調用無參數的change()方法來觸發該事件:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery</title>
<script src="/static/js/jquery-3.2.1.min.js"></script>
</head>
<body>
<input id="test-input" type="TEXT" name="change" value="change">
<input type="SUBMIT" value="submit">
<script>
var input=$('#test-input');
input.change(function(){
    console.log('changed.................');
});
input.val('test!!!!!!');
input.change();
</script>
</body>
</html>

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事件處理函數內執行,這是瀏覽器容許的,而button2click事件並未馬上執行popupTestWindow(),延遲執行的popupTestWindow()將被瀏覽器攔截。

相關文章
相關標籤/搜索