(jQuery) jQuery中的事件與動畫(上)

kimi013發表於2016-09-12

一、事件

1.1 $(document).ready()window.onload的比較

1.1.1 執行時機

  • $(document).ready()方法註冊的事件處理程式,在DOM完全就緒時就可以被呼叫,但是,這並不意味著這些元素關聯的檔案都已經下載完畢,如果指令碼中要獲取圖片的長度與寬度等屬性,請不要用此方法。

  • window.onload方法是在網頁中所有的元素(包括元素的所有關聯檔案)完全載入到瀏覽器後才執行,即JS此時才可以訪問網頁中的任何元素。

1.1.2 多次使用

  • $(document).ready()方法

function one() {
  alert(`one`);
}

function two() {
  alert(`two`);
}

$(document).ready(function() {
  one();
});

$(document).ready(function() {
  two();
});

執行程式碼後,會先彈出字串one對話方塊,然後再彈出字串two對話方塊。

  • window.onload

// 省略one與two函式的宣告
window.onload = one;
window.onload = two;

執行程式碼後,只彈出字串two對話方塊。因為load事件一次只能儲存對一個函式的引用,它會自動用後面的函式覆蓋前面的函式。因此不能在現在的行為上新增新的行為。
可以用下面的方法:

window.onload = function () {
  one();
  two();
}

雖然這樣的能解決某些問題,但還是不能滿足某些需求。例如有多個js檔案,每個檔案都要用到window.onload方法,這種情況下用上面的方法就會非常麻煩,而$(document).ready()就可以處理這些情況。

1.2 事件繫結bind

bind(type [, data], fn)

  • type:事件型別,包括clickmousedown等。

  • data:作為event.data屬性傳遞給事件物件的額外資料物件,可選。

  • fn:用來繫結的處理函式。

$(function() {
  $(`#panel h5.header`).bind(`mouseover`, function(event) {
    $(this).next().show();
  }).bind(`mouseout`, function(event) {
    $(this).next().hide();
  });
});

1.3 合成事件

1.3.1 hover()方法

hover(enterFn, leaveFn)

hover()方法用於模擬游標懸停事件。當游標移動到元素上時,會觸發指定的第一個函式(enterFn),當游標移出這個元素時,會觸發指定的第二個函式(leaveFn)。hover()方法替代的是bind(`mouseenter`)bind(`mouseleave`)

$(function() {
  $(`.#panel h5.header`).hover(function() {
    $(this).next().show();
  }, function() {
    $(this).next().hide();
  });
});

1.4 事件冒泡

1.4.1 什麼是冒泡

<body>
  <div class = "content">
    <span></span>
  </div>
</body>
// 為span繫結事件
$(`span`).bind(`click`, function(event) {
  alert(`Span is clicked.`);
});
// 為div繫結事件
$(`.content`).bind(`click`, function(event) {
  alert(`Div is clicked.`);
});
// 為body繫結事件
$(`body`).bind(`click`, function(event) {
  alert(`Body is clicked.`);
});

當點選<span>元素時,<span><div><body>元素的click事件依次被觸發。
事件會按照DOM的層次結構像水泡一樣不斷向上直至頂端。

1.4.2 事件冒泡引發的問題

  • 停止事件冒泡
    事件冒泡會引起預料之外的效果。可用stopPropagation()方法來停止冒泡。

$(`span`).bind(`click`, function(event) {
  event.stopPropagation();
  alert(`Span is clicked.`);
});

此時點選<span>元素時,只會執行<span>click事件。

  • 阻止預設行為
    可用preventDefault()方法來阻止元素的預設行為。

舉例,在專案中,經常需要驗證表單,在單擊“提交”按鈕時,驗證表單內容,例如某元素是否是必填欄位,某元素長度是否夠6位等,當表單不符合提交條件時,要阻止表單的提交(預設行為)。

$(function() {
  $(`#sub`).bind(`click`, function(event) {
    var username = $(`#username`).val();
    if (username === ``) {
      $(`#msg`).html(`<p>文框的值不能為空</p>`);
      event.preventDefault();
    }
  });
});

如果想同時對事件物件停止冒泡和預設行為,可以在事件處理函式return false。這是對在事件物件上同時呼叫stopPropagation()方法和event.preventDefault()

  • 事件捕獲
    事件捕獲和事件冒泡是剛好相反的兩個過程,事件捕獲是從最頂端往下開始觸發。

並非所有主流瀏覽器都支援事件捕獲,並且這個缺陷無法通過js來修復。

1.6 移除事件

`unbind([type], [data]);

第一個引數是事件型別,第二個引數是將要移除的函式:

  • 如果沒有引數,則刪除所有繫結的事件。

  • 如果提供了事件型別作為引數,則只刪除該型別的繫結事件。

  • 如果把繫結時傳遞的函式作為第二個引數,則只有這個特定的事件處理函式會被刪除。

1.7 one()方法

one(type, [data], fn)

one()方法的結構與bind()方法類似,使方法也與bind()方法相同。使用one()方法為元素繫結事件後,只在第一次觸發事件時,處理函式才執行,之後的觸發毫無作用。

1.8 模擬操作

trigger(type, [data])

  • 第一個引數是要觸發的事件型別

  • 第二個引數是要傳遞給事件處理函式的附加資料

1.8.1 常用模擬

使用trigger()方法

$(`#btn`).trigger(`click`);
// or
$(`#btn).click();

1.8.2 觸發自定義事件

$(`#btn`).bind(`myClick`, function () {
  // do sth
});

$(`#btn`).trigger(`myClick`);

1.8.3 傳遞資料

// 獲取資料
$(`#btn`).bind(`myClick`, function(event, msg1, msg2) {
  $(`#test`).append(`<p>` + msg1 + msg2 + `</p>`); 
});

// 傳遞兩個資料
$(`#btn`).trigger(`myClick`, [`我的自定義`, `事件`]);

1.8.4 執行預設操作

trigger()方法觸發事件後,會執行瀏覽器預設操作。
如果只想觸發繫結的事件,而不想執行瀏覽器的預設操作,可以使用triggerHandler()方法。

$(`input`).triggerHandler(`focus`);

1.9 其他用法

1.9.1 繫結多個事件型別

$(function() {
  $(`div`).bind(`mouseover mouseout`, function(event) {
    $(this).toggleClass(`over`);
  });
});

1.9.2 新增事件名稱空間,便於管理

$(function() {
  $(`div`).bind(`click.plugin`, function(event) {
    $(`body`).append(`<p>click event</p>`);
  });
  $(`div`).bind(`mouseover.plugin`, function (event) {
    $(`body`).append(`<p>mouseover event</p>`);
  })
  $(`div`).bind(`dbclick`, function(event) {
    $(`body`).append(`<p>dbclick event</p>`);
  });
  $(`button`).bind(`click`, function(event) {
    $(`div`).unbind(`.plugin`);
  });
});

點選<button>元素後,.plugin的名稱空間被刪除,而dbclick事件依然存在。

1.9.3 相同事件名稱,不同名稱空間執行方法

$(function() {
  $(`div`).bind(`click`, function(event) {
    $(`body`).append(`<p>click event</p>`);
  });
  $(`div`).bind(`click.plugin`, function(event) {
    $(`body`).append(`<p>click.plugin event</p>`);
  });
  $(`button`).bind(`click`, function(event) {
    $(`div`).trigger(`click!`); // 注意click後面的歎號
  });
});

trigger(`click!`)歎號的作用是隻觸發click事件,不觸發click.plugin事件。

相關文章