如何识别“;输入“;没有浏览器检测的事件

How to identify buggy behavior in "input" event without browser detection?

本文关键字:浏览器 检测 事件 输入 识别 何识别      更新时间:2023-09-26

我将从这个问题开始。当一个特定的浏览器有一个有缺陷的功能实现时,你的javascript需要知道当前浏览器是否有这个有缺陷的实现,这样它就可以使用另一种策略,你如何在不进行浏览器类型嗅探(通常认为这很糟糕)的情况下判断这个实现是否有缺陷?

这是整个情况。

我正在编写一些代码,希望使用"input"事件来获取用户对<input type="text">字段的更改通知(比"change"事件更有效),但当该事件不受支持时,它会使用一个更复杂的方案,涉及一堆其他事件。

由于"输入"事件仅在某些浏览器中受支持,我开始寻找一种对事件进行特征检测的方法(而不是浏览器用户代理嗅探),因为特征检测通常是一种更稳健的方法。因此,我看到了这篇伟大的文章,正是因为这样做,而这段代码似乎很有效:

var isEventSupported = (function(){
    var TAGNAMES = {
      'select':'input','change':'input',
      'submit':'form','reset':'form',
      'error':'img','load':'img','abort':'img'
    }
    function isEventSupported(eventName) {
      var el = document.createElement(TAGNAMES[eventName] || 'div');
      eventName = 'on' + eventName;
      var isSupported = (eventName in el);
      if (!isSupported) {
        el.setAttribute(eventName, 'return;');
        isSupported = typeof el[eventName] == 'function';
      }
      el = null;
      return isSupported;
    }
    return isEventSupported;
  })();

然后,我遇到了IE的问题(惊喜,惊喜)。虽然IE声称支持"输入"事件,并且它通过了上面的功能测试,并且大部分时间都能正常工作,但IE的支持非常糟糕。当用户按下退格键(以及其他缺失的行为)时,它甚至不会触发事件。因此,我不能在IE中依赖它。因此,我构建了这个漂亮干净的代码,它对"输入"事件进行了功能测试,并在存在时使用它的非常干净的实现,而在不存在时使用了更丑陋的工作,包括监视其他八个事件。现在,它在IE中被破坏了,因为"输入"事件的功能测试通过了,所以代码试图使用它,但它非常糟糕,所以不起作用。

由于这些IE错误显示在用户操作中,我想不出任何方法来设计javascript功能测试来识别错误行为。因此,我目前唯一的途径是求助于浏览器嗅探,如果浏览器是IE,则拒绝依赖"输入"标签。

除了浏览器嗅探之外,这里还有什么选项可以识别"输入"事件中的错误行为吗?如果必须进行浏览器嗅探,是否有一种方法可以通过行为而不是用户代理字符串来识别IE,该字符串可以自由伪造,并且不能保证准确?

jamie pate建议这样做:

   var broken = false,
        ta = angular.element('<textarea>').on('input', function(evt) {
            broken = true;
        });
    ta.attr('placeholder', 'IESUCKS');

因此,您可以在代码中检查"支持输入事件且未被破坏"。

请参阅https://github.com/angular/angular.js/issues/2614?source=c

如果您对跨浏览器的"输入更改"事件感兴趣,下面是我的实现:

function onInputChange(domInput, callback) {
    if (domInput.addEventListener) {
        domInput.addEventListener('input', callback, false); // Firefox, etc.
    } else if (domInput.attachEvent) {
        domInput.attachEvent('onpropertychange', callback); // IE
    }
}


用法示例:

var leInput = document.getElementById('myInput');
var leCallback = function () {
    // awesome stuff here
};
onInputChange(leInput, leCallback);


适用于所有浏览器,支持键盘输入和复制/粘贴。

然而,有一个例外,那就是那个被诅咒的IE9,在我写上面的代码时它还不存在。微软会考虑修复他们的错误吗?:''