2009-07-12 5 views
3

Представьте меня этот код:JavaScript, остановка дополнительные слушатели событий

var myFunc1 = function(event) { 
    alert(1); 
} 
var myFunc2 = function(event) { 
    alert(2); 
} 

element.addEventListener('click', myFunc1); 
element.addEventListener('click', myFunc2); 

Когда событие щелчка обжигают myFunc1 называется, то myFunc2. Но как мне (если это вообще возможно) остановить myFunc2 от вызова, если выполняется какое-то условие в myFunc1? event.stopPropagation() не является решением, так как это не проблема захвата/барботажа события.

Спасибо.

+0

Всегда ли они звонят вместе? –

+0

Нет, иногда я использую только один или другой. А слушатели добавляются в разные компоненты, поэтому их нельзя комбинировать. –

+0

Это stopProp! A! gation not stopProp! o! Я ставлю, что это просто опечатка здесь – epascarello

ответ

5

Есть еще одна проблема: порядок выполнения прослушивателей событий не определен. Вам нужно будет обработать отправку событий самостоятельно, чтобы обойти это, что приводит нас к некоторому варианту предложения llimllib.

function dispatchSleightEvent(evt) { 
    var listeners = evt.currentTarget.sleightListeners[evt.type]; 
    // can't use for-in because enumeration order is implementation dependent 
    for (var i=0; i<listeners.length; ++i) { 
     if (listeners[i]) { 
     if (! listeners[i].call(evt.currentTarget, evt)) { 
      return false; 
     } 
     } 
    } 
    return true; 
} 

function mixinSleightTarget(obj) { 
    if (! obj.sleightListeners) { 
    obj.sleightListeners = {} 
    obj.addSleightListener = function(type, listener) { 
     if (!this.sleightListeners[type]) { 
      this.sleightListeners[type] = []; 
      this.addEventListener(type, dispatchSleightEvent); 
     } 
     if (!this.sleightListeners[type+listener] { 
      this.sleightListeners[type+listener] = this.sleightListeners[type].length; 
      this.sleightListeners[type].push(listener); 
     } 
    } 
    obj.removeSleightListener = function(type, listener) { 
     if (this.sleightListeners[type+listener] { 
      delete this.sleightListeners[type][this.sleightListeners[type+listener]]; 
      delete this.sleightListeners[type+listener]; 
     }   
    } 
    } 
} 

Этот код полностью не проверен. Чтобы остановить отправку событий на одной цели, прослушиватель событий возвращает false. Если вам нужно больше скрывать данные, вы можете переписать выше с точки зрения функционального программирования, хотя это может привести к утечкам памяти.

+0

До тех пор, пока stopImmediatePropagation() не реализована, пользовательский обработчик событий является лучшим решением, поэтому я отметил его как ответ. Хотя вы правы, что заказ не определен, он определен в DOM Level-3 (FIFO), и каждый тест, который я сделал в Gecko, предполагает, что этот порядок согласован в текущей реализации (это для внутреннего приложения, которое нужно только работать в FF3). Пока что для простоты, в настоящее время я выбрал решение, подобное моему первому предшественнику. –

+0

Есть одна проблема, о которой я беспокоился, о том, что слушатели добавлены, но похоже, что на данный момент это не проблема. Лучший дизайн будет поддерживать явные зависимости слушателя. – outis

2

Начну с простейшего ответа, который удовлетворяет ограничениям, которые вы дали до сих пор. Если это не соответствует определенному условию, которое вы еще не указали, сообщите мне, и я обновлю его.

Только один обработчик кликов и функции вызова на основе условий. Ваш тестовый код будет:

var myFunc1 = function(event) { 
    alert(1); 
} 
var myFunc2 = function(event) { 
    alert(2); 
} 
var clickHandler = function(event) { 
    if (f1active) myFunc1(event); 
    if (f2active) myFunc2(event); 
} 

element.addEventListener('click', clickHandler); 
var f1active = true; 
var f2active = true; 

и вы можете, конечно же, установить любые условия, в которых вы хотите щелкнутьHandler.

+0

Проблема: а) Я не всегда использую оба слушателя одновременно, и б) слушатели добавляются в разные компоненты в большую модульную библиотеку кода, поэтому слияние их не только не имеет смысла, но также быть довольно сложным. –

3

Все еще ищете лучшее решение, но это может быть единственным способом сделать это:

var myFunc1 = function(event) { 
    alert(1); 
    if (something) { 
     event.cancel = true; 
    } 
} 
var myFunc2 = function(event) { 
    if (event.cancel) { 
     return; 
    } 
    alert(2); 
} 

document.body.addEventListener('click', myFunc1, false); 
document.body.addEventListener('click', myFunc2, false); 

Мысли/комментарии приветствуются.

5

Метод DOM Level 3 event.stopImmediatePropagation - это именно то, что мне нужно здесь. К сожалению, в настоящее время он не реализован ни в одном браузере (что я знаю).

+1

Это то, что я искал !!!!!! Большое спасибо! –

+1

Спасибо, что упомянули об этом.[В настоящее время он реализован во многих браузерах] (http://stackoverflow.com/a/18078452/1185136). –

0

Я второй вариант решения, похоже, вам нужно украсить или адаптировать существующую модель диспетчеризации событий DOM с вашим собственным диспетчером событий.

ли некоторый поиск и нашел эту ссылку, которая может или не может удовлетворить ваши потребности, основанные на реализации диспетчерского Actionscript, датированный 2007

http://positionabsolute.net/blog/2007/06/event-dispatcher.php

Конечно, я на самом деле не javascripter, так что дайте мне голову, если это не актуально.

+0

Ваша ссылка устарела – murtho

Смежные вопросы