13

感謝Perfection kills,我們可以使用下面的JavaScript來檢測事件支持:如何檢測`focusin`支持?

function hasEvent(ev) { 
    var elem = document.createElement('a'), 
     type = 'on' + ev, 
     supported = elem[type] !== undefined; 
    if (!supported) { 
     elem.setAttribute(type, 'return;'); 
     supported = typeof elem[type] === 'function'; 
    } 
    elem = null; 
    return supported; 
} 

這適用於約我需要它唯一的一次:檢測mouseenter支持;因爲它應該會在Chrome,Firefox等中返回錯誤hasEvent('mouseenter')

但現在我試圖「修復」不支持focusinfocusout事件的瀏覽器。 According to PPK,這基本上只是Firefox。不幸的是,由於以下原因,Chrome和Safari被列爲「不完整」支持:

Safari和Chrome僅通過addEventListener觸發這些事件;而不是傳統的註冊。

一般來說,這很好;無論如何,我只會使用addEventListener。它確實的意思,但是,通過elem.onfocusin !== undefined檢測支持將無法正常工作。我測試過它,這是真的:

<p>Do I support <a href="#">focusin</a>?</p> 

<script> 
var elem = document.getElementsByTagName('p')[0]; 

// hasEvent method defined here 
function listener() { 
    var response = hasEvent('focusin') ? 'Yes!' : 'No...'; 
    alert(response); 
} 

elem.addEventListener('focusin', listener, false); 
</script> 

以上提醒No...在Chrome!有什麼方法可以檢測瀏覽器是否支持focusin,而不使用瀏覽器嗅探?

+0

mouseenter&mouseover有沒有區別?或聚焦和聚焦?或聚焦和模糊? – Ibu

+1

@Ibu'mouseenter'不會起泡,而「mouseover」會起泡; 'focusin' /'focusout' * do *泡泡,'focus' /'blur'不要。 – sdleihssirhc

+1

另一個重要的事實是focusin和focusout事件對象具有指向已丟失/接收焦點的元素的'relatedTarget'屬性。 –

回答

3

這使用調用focus()觸發focusinhttp://jsfiddle.net/pimvdb/YXeD3/的事實。

元素必須可見並插入到DOM中,否則focusin不會因某種原因而被解僱。

var result = (function() { 
    var hasIt = false; 

    function swap() { 
     hasIt = true; // when fired, set hasIt to true 
    } 

    var a = document.createElement('a'); // create test element 
    a.href = "#"; // to make it focusable 
    a.addEventListener('focusin', swap, false); // bind focusin 

    document.body.appendChild(a); // append 
    a.focus(); // focus 
    document.body.removeChild(a); // remove again 

    return hasIt; // should be true if focusin is fired 
})(); 
+1

我喜歡這個想法,但是這種檢測方法有點讓人困惑,因爲它會改變頁面上的活動元素。 –

+0

如果這個答案也阻止了臨時錨元素獲得焦點,那麼這個答案會更好。那麼它不會有明顯的副作用。 (就像偷竊的焦點,如果網頁上的元素在頁面加載時試圖自動對焦怎麼辦?) –

4

的focusIn BEFORE目標元素獲得焦點&事件的內容應該被解僱,事件順序也似乎馬車

http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order

目前,只有IE瀏覽器的工作原理,按照規範:

Chrome/Safari: 
focus 
focusin 
DOMFocusIn 
blur 
focusout 
DOMFocusOut 
focus 
focusin 
DOMFocusIn 

Opera 12: 
focus 
DOMFocusIn 
focusin 
blur 
DOMFocusOut 
focusout 
focus 
DOMFocusIn 
focusin 

IE 8: 
focusin 
focus 
focusout 
focusin 
blur 
focus 

Firefox 14: 
focus 
blur 
focus 
+0

好吧,spec已經寫在IE的行爲之後,所以這並不令人驚訝。 –

+1

但IE行爲很好,即支持event.toElement/event.fromElement,其他瀏覽器不支持此事件的relativeTarget/toElement/fromElement – 4esn0k

-1

您可以測試("onfocusin" in document)

該方法具有輕便和不顯眼的優勢,並且它會告訴您瀏覽器是否支持focusin事件。(無法在Chrome,抱歉)

您可以使用下面的代碼,以獲得相同的行爲在所有瀏覽器(IE9 +,Chrome瀏覽器,火狐,邊緣)focusin事件:

var eventName, useCapture; 
if ("onfocusin" in document) { 
    eventName = "focusin"; 
    useCapture = false; 
} else {  
    eventName = "focus"; 
    useCapture = true; 
} 

document.body.addEventListener(eventName, function(event) { 
    event.target.style.background = "pink";  
    }, useCapture); 

JS小提琴這裏:https://jsfiddle.net/d306qm92/2/

關於Firefox的變通方法這裏的更多信息:https://developer.mozilla.org/en-US/docs/Web/Events/focus#Event_delegation

UPDATE:正如上面所說的,測試將錯誤在Chrome上說「false」,但代碼示例將按預期工作,因爲Chrome支持這兩種方法(focusinfocususeCapture)。