Как идентифицировать ошибочное поведение в "входном" событии без обнаружения браузером?
Начну с вопроса. Если в конкретном браузере имеется ошибочная реализация функции, и ваш javascript должен знать, имеет ли текущий браузер эту ошибочную реализацию или нет, чтобы он мог использовать альтернативную стратегию, как выяснить, если реализация содержит ошибки, не анализируя тип браузера? (что вообще считается плохим)?
Вот и вся ситуация.
Я работал над кодом, который хочет использовать событие "input" для получения уведомлений о пользовательских изменениях в <input type="text">
поле (работает гораздо активнее, чем событие "изменение"), но когда это событие не поддерживается, оно использует гораздо более сложную схему, включающую множество других событий.
Поскольку событие "input" поддерживается только в некоторых браузерах, я отправился на поиски способа обнаружения функции для этого события (а не прослушивания агента пользователя браузера), поскольку функция обнаружения, как правило, является более надежным способом выполнения действий. Таким образом, я наткнулся на эту замечательную статью, и именно этот код работает:
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 подразумевает поддержку события "input" и проходит вышеописанный функциональный тест, и он работает большую часть времени, поддержка IE глючит до чертиков. Это даже не вызывает событие, когда пользователь нажимает клавишу возврата (среди других отсутствующих поведений). Таким образом, я не могу положиться на это в IE. Итак, я построил этот хороший чистый код, который выполнил функциональный тест для события "input" и использует его очень чистую реализацию, когда присутствует, а когда нет, использовал этот гораздо более уродливый обходной путь, включающий мониторинг восьми других событий. Теперь он отключен в IE, потому что тестирование функции для события "input" проходит, поэтому код пытается его использовать, но он чертовски глючит и не работает.
Так как эти ошибки IE обнаруживаются при действиях пользователя, я не могу придумать, как разработать тест функции javascript для выявления ошибочного поведения. Таким образом, мой единственный текущий путь - прибегнуть к снифферу браузера и отказаться от использования тега input, если браузер IE.
Есть ли здесь какие-либо опции для выявления ошибочного поведения в событии "input", кроме перехвата браузера? Если нужно было проанализировать браузер, есть ли способ идентифицировать IE по поведению, а не по строке агента пользователя, которая может быть свободно подделана и не гарантирует ее точность?
2 ответа
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, которого не было в то время, когда я писал приведенный выше код. Будет ли Microsoft когда-нибудь исправлять их ошибку?:\