13

感谢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,因为它应该。

但现在我正在尝试“修复”不支持focusinandfocusout事件的浏览器。根据 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,而不使用浏览器嗅探?

4

3 回答 3

4

focusin & focusout 应该在目标元素接收焦点之前触发,事件顺序也似乎有问题

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
于 2012-07-30T13:36:52.220 回答
3

focus()这使用了调用触发器的事实:http focusin: //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
})();
于 2011-09-07T17:15:47.847 回答
0

你可以测试一下("onfocusin" in document)

这种方法的优点是轻巧不显眼,它会告诉你浏览器是否支持该focusin事件。(不在 Chrome 上,抱歉)

focusin您可以使用以下代码在所有浏览器(IE9+、Chrome、Firefox、Edge)上获得与事件相同的行为:

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

更新:如上所述,测试在 Chrome 上会错误地说“假”,但是代码示例将按预期工作,因为 Chrome 支持这两种方法(focusinfocuswith useCapture)。

于 2016-04-29T13:03:01.933 回答