focus
:當focusable元素得到焦點時,不支持冒泡;focusin
:和focus
同樣,只是此事件支持冒泡;blur
:當focusable元素失去焦點時,不支持冒泡;focusout
:和blur
同樣,只是此事件支持冒泡;javascript
之前一直覺得全部事件都是支持冒泡的,都是能夠cancel的,查閱了[MDN上相關資料](https://developer.mozilla.org/en-US/docs/Web/Events)後,才發現有些事件支持冒泡,有些事件並不支持冒泡;有些事件有默認行爲(這類事件能夠cancel),有些事件壓根兒就沒有默認行爲(這類事件就不能 cancel )。從 MDN 上能夠清楚的看到 focus
和blur
這2種事件不支持冒泡,支持冒泡的事件是focusin
和focusout
。html
對於同時支持這4個事件的瀏覽器,事件執行順序爲focusin > focus > focusout > blur,代碼示例以下:java
html代碼chrome
<div class="parent"> <input type="text" /> </div> <div class="log"></div>
javascript代碼瀏覽器
function log(str){ $('.log').append($('<div/>').text(str)); } $('.parent') .focusin(function(){log('div focusin');}) .focusout(function(){log('div focusout');}) .focus(function(){log('div focus');}) .blur(function(){log('div blur');}); $('input') .focusin(function(){log('input focusin');}) .focusout(function(){log('input focusout');}) .focus(function(){log('input focus');}) .blur(function(){log('input blur');});
執行結果app
從執行結果能夠看到4個事件的執行順序,同時也能夠看到 focus
/blur
是不支持冒泡的,因此.parent 元素綁定的focus
和blur
事件回調並無觸發。this
幾乎全部的瀏覽器都支持focus
和blur
事件,但對於focusin
和focusout
就不是這樣理想了。Firefox中不支持focusin
和focusout
事件;chrome和safari中只有經過addEventListener方式綁定事件才能正常使用,其餘方式綁定都不行;spa
面對這樣的瀏覽器支持彷佛很頭痛,慶幸的是jQuery對focusin
和focusout
作了兼容,使用$.focusin
和$.focusout
實現事件綁定,在全部瀏覽器中都支持;代理
focus
和blur
如何實現事件代理事件代理簡單來講就是將子元素事件綁定在祖先元素上,之因此可以這樣作,得益於標準事件模型的捕獲和冒泡。咱們知道在標準事件模型中,一個事件的觸發會經歷三個階段:捕獲階段+目標階段+冒泡階段,有了捕獲和冒泡才能實現事件代理。由前面介紹可知,focus
和blur
不支持冒泡,但其支持捕獲,但 IE 中事件模型沒有捕獲只有冒泡,因此在非IE瀏覽器中能夠經過在捕獲階段進行事件綁定實現事件代理。那麼針對IE瀏覽器怎麼實現呢?經過支持冒泡的是focusin
和focusout
實現就能夠了。代碼示例以下:code
html 代碼
<form name="form"> <input type="text" name="name" value="Your name"> <input type="text" name="surname" value="Your surname"> </form>
javascript 代碼
function addColor(){ this.style.background="red"; } var form = document.forms['form']; if (form.addEventListener) { // 非 IE 瀏覽器 form.addEventListener('focus', addColor, true); }else{ // IE form.onfocusin = addColor }
在本文的第一小節提到了一個 focusable 元素的概念,我以爲有必要在這裏解釋一下什麼是focusable 元素。
默認狀況下,只有部分html元素能得到鼠標焦點如input
,很大一部分html元素是不能得到鼠標焦點的如div
,這些可以得到鼠標焦點的元素就是focusable 元素。要想一個元素得到焦點,能夠經過三種方式:
鼠標點擊
tab 鍵
調用focus()方法
那麼默認狀況下,哪些元素是focusable 元素
window:當頁面窗口從隱藏變成前置可見時,focus 事件就會觸發
表單元素(form controllers):input/option/textarea/button
連接元素(links):a標籤、area標籤(必需要帶 href 屬性,包括 href 屬性爲空)
設置了 tabindex 屬性(tabindex 值非-1)的元素
設置了contenteditable = "true"屬性的元素
tabindex
屬性默認狀況下就能 focusable 的元素太少,若是想讓一個 div
元素成爲 focusable 的元素怎麼作呢?很簡單,設置 tabindex 屬性便可!
tabindex 有2個做用:
使一個元素變成 focusable
只要在元素上設置了 tabindex 屬性,無論此屬性的值設爲多少,此元素都將變成focusable元素。
定義屢次按下 TAB 鍵時得到焦點的元素順序
tabindex 屬性的值能夠正數、0、負數,當屢次按下TAB鍵,首先是tabindex爲正數的元素得到焦點,順序是:tabindex=一、tabindex=二、tabindex=三、tabindex=...,最後是tabindex=0的元素得到焦點。注意:tabindex爲負數的元素不能經過 TAB 鍵得到焦點,只能經過鼠標點擊或者調用focus()方法才能得到焦點。示例代碼以下:
<ul> <li tabindex="1" onfocus="showFocus(this)">One</li> <li tabindex="0" onfocus="showFocus(this)">Zero</li> <li tabindex="2" onfocus="showFocus(this)">Two</li> <li tabindex="-1" onfocus="showFocus(this)">Minus one</li> <li tabindex="-2" onfocus="showFocus(this)">Minus two</li> </ul>