Как правильно подавить событие при подключении своего обработчика?
Столкнулся с ситуацией, когда Fire Fox не хочет подавлять возникшее событие внутри обработчика этого события, если обработчик подключен с помощью addHandler().
Для демонстрации создал такой пример: на странице находится поле input с установленным в нем фокусом (курсором). При клике по любому месту страницы я подавляю событие document.onmousedown, что не должно привести к процессу потери фокуса данным инпутом. В Google Chrome и Opera это работает. Курсор остается в поле инпута. Но Fire Fox не убивает возникшее событие mousedown, поэтому броузер порождает input.onblur, т.е. фокус с инпута снимается. <html><body> <script type="text/javascript"> //////////////////// function addHandler(object, event, handler, useCapture) // кроссбраузерное добавление обработчика событий { if (object.addEventListener) {object.addEventListener(event,handler,useCapture ? useCapture : false)} else if (object.attachEvent){object.attachEvent('on' + event, handler)} }; function cancelEvent(e) // кроссбраузерная функция подавления события { e = e ? e : window.event; if (e.stopPropagation) e.stopPropagation(); else if (e.preventDefault) e.preventDefault(); e.cancelBubble=true;e.cancel=true;e.returnValue=false;return false; }; function fixEvent(e) { e = e || window.event; if (e.pageX == null && e.clientX != null) { var html = document.documentElement; var body = document.body; e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0); e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0); } if (!e.which && e.button) e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) ); return e; }; //////////////////// // эксперимент: function MouseDownHandler(e) { e = fixEvent(e); return cancelEvent(e); }; addHandler(document, 'mousedown', MouseDownHandler); // при подключении обработчика таким образом событие MouseDown в FireFox не уничтожается //document.onmousedown = MouseDownHandler; // при подключении обработчика таким образом событие MouseDown уничтожается нормально var inp = document.createElement('input'); document.body.appendChild(inp); //inp.onblur = function() {alert('потеря фокуса!')}; inp.focus(); </script> test </body></html>Обратил внимание, что если не пользоваться addHandler(), а тупо повесить свой обработчик так: document.onmousedown = MouseDownHandler;то Fire Fox начинает работать нормально. К сожалению, я не могу сделать такое присвоение, т.к. на document.onmousedown уже висит ещё один (чужой) обработчик. Читал, что при добавлении своего обработчика можно еще задавать дополнительно два параметра и задавать какие-то фазы..., но что-то мне там не всё ясно, могут ли эти фазы исправить положение? Как всё же правильно подавлять события? |
как ты думаешь, для чего предназначены методы preventDefault и stopPropagation?
|
В функции cancelEvent(e) была досадная ошибка в этих двух строчках:
if (e.stopPropagation) e.stopPropagation(); else if (e.preventDefault) e.preventDefault();А надо так: if (e.stopPropagation) // отмена всплывания события (стандарт W3C) e.stopPropagation(); else e.cancelBubble=true; if (e.preventDefault) // отмена действия браузера по-умолчанию e.preventDefault(); else e.returnValue=false;А лучше так: e.stopPropagation ? e.stopPropagation() : (e.cancelBubble=true); // отмена всплытия события e.preventDefault ? e.preventDefault() : (e.returnValue=false); // отмена действия браузера по-умолчаниюИ FireFox заработал нормально. Одно не понятно: почему ошибка проявлялась только в FireFox, а в других броузерах нет? |
Часовой пояс GMT +3, время: 21:57. |