JavaScript, остановите дополнительных слушателей событий - PullRequest
5 голосов
/ 12 июля 2009

Представьте, что у меня есть этот код:

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

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

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

Спасибо.

Ответы [ 5 ]

9 голосов
/ 12 июля 2009

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

6 голосов
/ 12 июля 2009

Есть еще одна проблема: порядок выполнения прослушивателей событий не определен. Чтобы обойти это, вам нужно будет самостоятельно обработать отправку события, что приведет нас к некоторому варианту предложения 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. Если вы хотите скрыть больше данных, вы можете переписать вышесказанное с точки зрения функционального программирования, хотя это может привести к утечкам памяти.

4 голосов
/ 12 июля 2009

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

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);

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

2 голосов
/ 12 июля 2009

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

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

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;

и вы можете, конечно, поставить любые условия в clickHandler.

0 голосов
/ 12 июля 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...