Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 20.07.2011, 20:13
Профессор
Отправить личное сообщение для Маэстро Посмотреть профиль Найти все сообщения от Маэстро
 
Регистрация: 02.07.2010
Сообщений: 642

Как правильно подавить событие при подключении своего обработчика?
Столкнулся с ситуацией, когда 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 уже висит ещё один (чужой) обработчик.
Читал, что при добавлении своего обработчика можно еще задавать дополнительно два параметра и задавать какие-то фазы..., но что-то мне там не всё ясно, могут ли эти фазы исправить положение?
Как всё же правильно подавлять события?
Ответить с цитированием
  #2 (permalink)  
Старый 23.07.2011, 16:39
Профессор
Отправить личное сообщение для tenshi Посмотреть профиль Найти все сообщения от tenshi
 
Регистрация: 20.03.2008
Сообщений: 1,183

как ты думаешь, для чего предназначены методы preventDefault и stopPropagation?
__________________
.ня
Ответить с цитированием
  #3 (permalink)  
Старый 03.09.2011, 11:46
Профессор
Отправить личное сообщение для Маэстро Посмотреть профиль Найти все сообщения от Маэстро
 
Регистрация: 02.07.2010
Сообщений: 642

В функции 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, а в других броузерах нет?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно прописать свой код в .js Всеми_Любимый Элементы интерфейса 6 23.02.2010 21:34
Ошибка при добавлении обработчика к событию Riim Events/DOM/Window 32 19.01.2010 14:17
Как правильно послать XML в POST запросе LowCoder AJAX и COMET 10 15.07.2009 23:20
Как правильно обработать событие? BAnder Events/DOM/Window 19 03.02.2009 14:09
Как правильно оформить Send() Алекс97 AJAX и COMET 20 30.10.2008 19:19