如何检测`focusin`支持?

时间:2011-09-07 16:56:49

标签: javascript javascript-events browser-feature-detection focusin

感谢Perfection kills,我们可以使用以下JavaScript来检测事件支持:

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支持; hasEvent('mouseenter')将在Chrome,Firefox等中返回false。

但现在我正在尝试“修复”不支持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>

Chrome中的上述提醒No... !!有没有办法检测浏览器是否支持focusin,而不使用浏览器嗅探?

3 个答案:

答案 0 :(得分:4)

焦点&amp;焦点输出应该在目标元素获得焦点之前被触发,事件顺序也似乎是错误的

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

答案 1 :(得分: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
})();

答案 2 :(得分:-1)

您可以测试("onfocusin" in document)

此方法的优点是轻巧且不引人注目,并且它会告诉您浏览器是否支持focusin事件。(不在Chrome上,对不起)

您可以使用以下代码在所有浏览器(IE9 +,Chrome,Firefox,Edge)上获得与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

更新:如上所述,测试会错误地说&#34; false&#34;尽管如此,在Chrome上,代码示例仍可按预期工作,因为Chrome支持两种方法(focusinfocususeCapture)。