国产gaysexchina男同gay,japanrcep老熟妇乱子伦视频,吃奶呻吟打开双腿做受动态图,成人色网站,国产av一区二区三区最新精品

DOM 事件

2018-07-10 15:14 更新
Table of Contents generated with DocToc

DOM 事件

何為 DOM 事件,HTML DOM 使JavaScript 有能力對(duì) HTML 事件做出反應(yīng)。(例如,點(diǎn)擊 DOM 元素,鍵盤被按,輸入框輸入內(nèi)容以及頁(yè)面加載完畢等)

事件流

一個(gè) DOM 事件可以分為捕獲過(guò)程、觸發(fā)過(guò)程、冒泡過(guò)程。 DOM 事件流為 DOM 事件的處理及執(zhí)行的過(guò)程。下面以一個(gè)<a>元素被點(diǎn)擊為例。

  1. [紅虛線]Capture Phase(事件捕獲過(guò)程)當(dāng) DOM 事件發(fā)生時(shí),它會(huì)從window節(jié)點(diǎn)一路跑下去直到觸發(fā)事件元素的父節(jié)點(diǎn)為止,去捕獲觸發(fā)事件的元素。
  2. [紅綠實(shí)線]Target Phase(事件觸發(fā)過(guò)程)當(dāng)事件被捕獲之后就開(kāi)始執(zhí)行事件綁定的代碼
  3. [綠虛線]Bubble Phase(冒泡過(guò)程)當(dāng)事件代碼執(zhí)行完畢后,瀏覽器會(huì)從觸發(fā)事件元素的父節(jié)點(diǎn)開(kāi)始一直冒泡到window元素(即元素的祖先元素也會(huì)觸發(fā)這個(gè)元素所觸發(fā)的事件

關(guān)于捕獲過(guò)程的補(bǔ)充

如果有一個(gè)支持三個(gè)階段的事件,它一定在觸發(fā)時(shí)遵循下面的順序:

Capture -> Target -> Bubbling

使用下面的代碼來(lái)舉例:

// 添加Capture階段事件
docuemnt.addEventListener('click',function(){
    alert('capture:'+1);
},true);
tableNode.addEventListener('click',function(){
    alert('capture:'+2);
},true);
tdNode.addEventListener('click',function(){
    alert('capture:'+3);
},true);

// 添加Bubbling階段事件
docuemnt.addEventListener('click',function(){
    alert('bubble:'+1);
});
tableNode.addEventListener('click',function(){
    alert('bubble:'+2);
});
tdNode.addEventListener('click',function(){
    alert('bubble:'+3);
});

輸出結(jié)果為:

capture:1
capture:2
capture:3
bubble:3
bubble:2
bubble:1

// 對(duì)document添加了三個(gè)bubbling階段的事件
document.addEventListener('click',function(){
    alert(1);
});
document.addEventListener('click',function(){
    alert(2);
});
document.addEventListener('click',function(){
    alert(3);
});

如上面的代碼所示,其為同一節(jié)點(diǎn)添加了同一階段的多個(gè)事件,那執(zhí)行順序如何呢? 早期并沒(méi)有規(guī)范定義,DOM 3 中規(guī)范已經(jīng)明確規(guī)定 同一節(jié)點(diǎn)同一階段的事件應(yīng)按照注冊(cè)函數(shù)的順序執(zhí)行。

在實(shí)際項(xiàng)目過(guò)程中,某些情況下比如若干的組件或者模塊都需要監(jiān)聽(tīng)某個(gè)節(jié)點(diǎn)的某個(gè)事件,但是組件或者模塊的生成(即添加事件的時(shí)機(jī))是不一定保證順序的,所以這個(gè)情況下如果某個(gè)組件對(duì)這個(gè)節(jié)點(diǎn)的這個(gè)事件的優(yōu)先級(jí)特別高(需要保證必須先觸發(fā)這個(gè)組件里的這個(gè)事件)而這個(gè)平臺(tái)又支持這個(gè)階段事件的話可以添加 capture 階段事件,用三階段的順序來(lái)保證,比如移動(dòng)平臺(tái)模擬手勢(shì)的實(shí)現(xiàn)會(huì)添加 document 上 touchXXX 的 capture 階段事件,以優(yōu)先識(shí)別手勢(shì)操作 當(dāng)然實(shí)踐過(guò)程中考慮到不同瀏覽器對(duì)三階段支持的情況的差異,大部分情況下都采用的是 bubbling 階段的事件

—— 蔡劍飛 網(wǎng)易前端工程師

NOTE:低版本 IE 中并未實(shí)現(xiàn)捕獲過(guò)程。也不是所有事件均存在這三個(gè)完整的過(guò)程(例如 load 沒(méi)有冒泡事件)

NOTE+:在這三個(gè)階段中無(wú)論將事件捕獲事件處理注冊(cè)到任意一個(gè)父或祖父節(jié)點(diǎn)上都會(huì)被觸發(fā)事件。

事件注冊(cè)

事件注冊(cè),取消以及觸發(fā)其作用對(duì)象均為一個(gè) DOM 元素。

注冊(cè)事件

eventTarget.addEventListener(type, listener[,useCapture])
  • evenTarget 表示要綁定事件的DOM元素
  • type 表示要綁定的事件,如:"click"
  • listener 表示要綁定的函數(shù)
  • useCapture 可選參數(shù),表示是否捕獲過(guò)程

NOTE:useCapture 為設(shè)定是否為捕獲過(guò)程,默認(rèn)事件均為冒泡過(guò)程,只有 useCapture 為 true 時(shí)才會(huì)啟用捕獲過(guò)程。

// 獲取元素
var elem = document.getElemenyById('id');

// 事件處理函數(shù)
var clickHandler = function(event) {
  // statements
};

// 注冊(cè)事件
elem.addEventListener('click', clickHandler, false);

// 第二種方式,不建議使用
elem.onclick = clickHandler;
// 或者來(lái)彌補(bǔ)只可觸發(fā)一個(gè)處理函數(shù)的缺陷
elem.onclick = function(){
  clickHandler();
  func();
  // 其他處理函數(shù)
};

取消事件

eventTarget.removeEventListener(type, listener[,useCapture]);
  • evenTarget 表示要綁定事件的DOM元素
  • type 表示要綁定的事件,如:"click"
  • listener 表示要綁定的函數(shù)
  • useCapture 可選參數(shù),表示是否捕獲過(guò)程
// 獲取元素
var elem = document.getElemenyById('id');

// 取消事件
elem.removeEventListener('click', clickHandler, false);

// 第二種方式。不建議使用
elem.onclick = null;

觸發(fā)事件

點(diǎn)擊元素,按下按鍵均會(huì)觸發(fā) DOM 事件,當(dāng)然也可以以通過(guò)代碼來(lái)觸發(fā)事件。

eventTarget.dispatchEvent(type);

// 獲取元素
var elem = document.getElemenyById('id');

// 觸發(fā)事件
elem.dispatchEvent('click');

瀏覽器兼容型

以上均為 W3C定義的標(biāo)準(zhǔn)定義,但早期瀏覽器 IE8 及其以下版本,均沒(méi)有采用標(biāo)準(zhǔn)的實(shí)現(xiàn)方式。不過(guò)這些低版本瀏覽器也提供了對(duì)于 DOM 事件的注冊(cè)、取消以及觸發(fā)的實(shí)現(xiàn)。

事件注冊(cè)與取消,attchEvent/detachEvent。事件觸發(fā),fireEvent(e),其也不存在捕獲階段(Capture Phase)。

兼容低版本代碼實(shí)現(xiàn)

注冊(cè)事件

var addEvent = document.addEventListener ?
  function(elem, type, listener, useCapture) {
    elem.addEventListener(type, listener, useCapture);
  } :
  function(elem, type, listener, useCapture) {
    elem.attachEvent('on' + type, listener);
  }

取消事件

var addEvent = document.removeElementListener ?
  function(elem, type, listener, useCapture) {
    elem.removeElementListener(type, listener, useCapture);
  } :
  function(elem, type, listener, useCapture) {
    elem.detachEvent('on' + type, listener);
  }

事件對(duì)象

調(diào)用事件處理函數(shù)時(shí)傳入的信息對(duì)象,這個(gè)對(duì)象中含有關(guān)于這個(gè)事件的詳細(xì)狀態(tài)和信息,它就是事件對(duì)象 event。其中可能包含鼠標(biāo)的位置,鍵盤信息等。

// 獲取元素
var elem = document.getElemenyById('id');

// 事件處理函數(shù)
var clickHandler = function(event) {
  // statements
};

// 注冊(cè)事件
elem.addEventListener('click', clickHandler, false);

NOTE:在低版本 IE 中事件對(duì)象是被注冊(cè)在 window 之上而非目標(biāo)對(duì)象上。使用下面的兼容代碼既可解決。

var elem = document.getElemenyById('id');

// 事件處理函數(shù)
var clickHandler = function(event) {
  event = event || window.event;
  // statements
};

屬性和方法

通用屬性和方法

屬性

  • type 事件類型
  • target(srcElement IE 低版本) 事件觸發(fā)節(jié)點(diǎn)
  • currentTarget 處理事件的節(jié)點(diǎn)

方法

  • stopPropagation 阻止事件冒泡傳播
  • preventDefault 阻止默認(rèn)行為
  • stopImmediatePropagation 阻止冒泡傳播
阻止事件傳播

event.stopPropagation()(W3C規(guī)范方法),如果在當(dāng)前節(jié)點(diǎn)已經(jīng)處理了事件,則可以阻止事件被冒泡傳播至 DOM 樹(shù)最頂端即 window 對(duì)象。

event.stopImmediatePropagation() 此方法同上面的方法類似,除了阻止將事件冒泡傳播值最高的 DOM 元素外,還會(huì)阻止在此事件后的事件的觸發(fā)。

event.cancelBubble=true 為 IE 低版本中中對(duì)于阻止冒泡傳播的實(shí)現(xiàn)。

阻止默認(rèn)行為

默認(rèn)行為是指瀏覽器定義的默認(rèn)行為(點(diǎn)擊一個(gè)鏈接的時(shí)候,鏈接默認(rèn)就會(huì)打開(kāi)。當(dāng)我們雙擊文字的時(shí)候,文字就會(huì)被選中),比如單擊鏈接可以打開(kāi)新窗口。

Event.preventDefault() 為 W3C 規(guī)范方法,在 IE 中的實(shí)現(xiàn)方法為 Event.returnValue=false。

事件分類

Event

事件類型是否冒泡元素默認(rèn)事件元素例子
loadNOWindow, Document, ElementNonewindow, image, iframe
unloadNOWindow, Document, ElementNonewindow
errorNOWindow, ElementNonewindow, image
selectNOElementNoneinput, textarea
abortNOWindow, ElementNonewindow, image
window
  • load 頁(yè)面全部加載完畢
  • unload 離開(kāi)本頁(yè)之前的卸載
  • error 頁(yè)面異常
  • abort 取消加載
image
  • load 圖片加載完畢
  • error 圖標(biāo)加載錯(cuò)誤
  • abort 取消圖標(biāo)加載

在目標(biāo)圖標(biāo)不能正常載入時(shí),載入備份替代圖來(lái)提供用戶體驗(yàn)。

<img src="http://sample.com/img.png" rel="external nofollow"  onerror="this.src='http://sample.com/default.png'">

UIEvent

事件類型是否冒泡元素默認(rèn)事件元素例子
resizeNOWindow, ElementNonewindow, iframe
scrollNO/YESDocument, ElementNonedocument, div

NOTE:resize 為改變?yōu)g覽器或iframe的窗體大小時(shí)會(huì)觸發(fā)事件,scroll 則會(huì)在滑動(dòng)內(nèi)容時(shí)觸發(fā),作用于 Document 則不會(huì)冒泡,作用于內(nèi)部元素則會(huì)冒泡。

MouseEvent

DOM 事件中最常見(jiàn)的事件之一。

事件類型是否冒泡元素默認(rèn)事件元素例子
clickYESElementfocus/activationdiv
dbclickYESElementfocus/activation/selectdiv
mousedownYESElementdrag/scroll/text selectiondiv
mosuemoveYESElementNonediv
mouseoutYESElementNonediv
mouseoverYESElementNonediv
mouseupYESElementcontext menudiv
mouseenterNOElementNonediv
mouseleaveNOElementNonediv

NOTE:mouseenter 與 mouseover 的區(qū)別為前者在鼠標(biāo)在子元素直接移動(dòng)不會(huì)觸發(fā)事件,而后者會(huì)觸發(fā)。mouseleave 與 mouseout 同上相似。

屬性
  • clientX, clientX
  • screenX, screenY
  • ctrlKey, shiftKey, altKey, metaKey 如果被按下則為真(true)
  • button(0, 1, 2) 鼠標(biāo)的間位

MouseEvent 順序

鼠標(biāo)的移動(dòng)過(guò)程中會(huì)產(chǎn)生很多事件。事件的監(jiān)察頻率又瀏覽器決定。

例子:從元素 A 上方移動(dòng)過(guò)

mousemove -> mouseover(A) -> mouseenter(A) -> mousemove(A) -> mouseout(A) -> mouseleave(A)

例子:點(diǎn)擊元素

mousedown -> [mousemove] -> mouseup -> click

實(shí)例:拖動(dòng)元素
<div id="div0"></div>
<style media="screen">
  #div0 {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
    border: 1px solid black;
  }
</style>
var elem = document.getElemenyById('div0');
var clientX, clientY, isMoving;
var mouseDownHandler = function(event) {
  event = event || window.event;
  clientX = event.clientX;
  clientY = event.clientY;
  isMoving = true;
}

var mouseMoveHandler = function(event) {
  if (!isMoving) return;
  event = event || window.event;
  var newClientX = event.clientX,
      newClientY = event.clientY;
  var left = parseInt(elem.style.left) || 0,
      top = parseInt(elem.style.top) || 0;
  elem.style.left = left + (newClientX - clientX) + 'px';
  elem.style.top = top + (newClientY - clientY) + 'px';
  clientX = newClientX;
  clientY = newClientY;
}

var mouseUpHandler = function() {
  isMoving = false;
}

addEvent(elem, 'mousedown', mouseDownHandler);
addEvent(elem, 'mouseup', mouseUpHandler);
addEvent(elem, 'mousemove', mouseMoveHandler);

滾輪事件(Wheel)

事件類型是否冒泡元素默認(rèn)事件元素例子
wheelYESElementscroll or zoom documentdiv

屬性

  • deltaMode 鼠標(biāo)滾輪偏移量的單位
  • deltaX
  • deltaY
  • deltaZ

FocusEvent

其用于處理元素獲得或失去焦點(diǎn)的事件。(例如輸入框的可輸入狀態(tài)則為獲得焦點(diǎn),點(diǎn)擊外部則失去焦點(diǎn))

事件類型是否冒泡元素默認(rèn)事件元素例子
blurNOWindow, ElementNonewindow, input
focusNOWindow, ElementNonewindow, input
focusinNOwindow, ElementNonewindow, input
focusoutNOwindow, ElementNonewindow, input

NOTE:blur 失去焦點(diǎn)時(shí),focus 獲得焦點(diǎn)時(shí),focusin 即將獲得焦點(diǎn),focusout即將失去焦點(diǎn)。

屬性

一個(gè)元素失去,既另一個(gè)元素獲得焦點(diǎn)。這里的 relatedTarget 則為相對(duì)的那個(gè)元素。

  • relatedTarget

InputEvent

輸入框輸入內(nèi)容則會(huì)觸發(fā)輸入事件。

事件類型是否冒泡元素默認(rèn)事件元素例子
beforeInputYESElementupdate DOM Elementinput
inputYESElementNoneinput

NOTE:beforeInput 為在按鍵按下后即將將輸入字符顯示之前生成的事件。

NOTE+:IE 并沒(méi)有 InputEvent 則需使用 onpropertychange(IE) 來(lái)代替。

KeyboardEvent

其用于處理鍵盤事件。

事件類型是否冒泡元素默認(rèn)事件元素例子
keydownYESElementbeforeInput/input/focus/blur/activationdiv, input
keyupYESElementNonediv, input

屬性

  • key 按下的鍵字符串
  • code
  • ctrlKey, shiftKey, altKey, metaKey
  • repeat 代表按鍵不松開(kāi)為 true
  • keyCode
  • charCode
  • which

事件代理

事件代理是指在父節(jié)點(diǎn)上(可為元素最近的父節(jié)點(diǎn)也可為上層的其他節(jié)點(diǎn))處理子元素上觸發(fā)的事件,其原理是通過(guò)事件流機(jī)制而完成的。可以通過(guò)事件對(duì)象中獲取到觸發(fā)事件的對(duì)象(如下所示)。

var elem = document.getElemenyById('id');
elem.addEventListener('click', function(event) {
  var e = event || window.event;
  var target = e.target || e.srcElement;
  // statements
});

優(yōu)點(diǎn)

  • 需要管理的事件處理函數(shù)更少
  • 內(nèi)存分配更少,更高效
  • 增加與刪除子節(jié)點(diǎn)可以不額外處理事件

缺點(diǎn)

  • 事件管理的邏輯變的復(fù)雜(因?yàn)槊芭輽C(jī)制)


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)