2013-06-30 4 views
0

EDIT: Мне нужно вызвать одну функцию, которая извлекает данные и перезагружает содержимое страницы. Но это нужно вызывать, когда другая функция извлекает данные (webSql). Я не могу использовать обратный вызов WebSql, поскольку переменные выходят за рамки. Поэтому я создал собственное событие и добавил слушателя во вторую область функций. Поэтому, когда данные извлекаются, я отправляю событие в первой области функции. Теперь проблема, если страница была перезагружена более одного раза, слушатели будут добавляться несколько раз, и все будут вызваны, которые я не хочу.Удалить анонимных прослушивателей событий перед добавлением новых

Мне нужно убедиться, что только одна функция прослушивает пользовательское событие. Сейчас я удаление слушателя, как только его вызывается так:

document.addEventListener("customEvent", function() { 
    actualCallBack(var1, var2); // Since I need to pass parameters I need to use callBack within an anonymous function. 
    this.removeEventListener("customEvent", arguments.callee, false); 
}, false); 

Но проблема анонимная функция будет удалена только после его вызова в первую очередь. Существует возможность прослушивания, добавляя много раз. Как удалить прослушиватели событий перед добавлением нового?

document.removeEventListener("customEvent"); 
document.addEventListener(...); 

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

+0

IIRC, 'cloneNode' клонирует все, кроме прослушивателей событий. Выполнение этого в 'document'-scope может быть веселым, хотя .. – fjdumont

+1

Одним из способов было бы привязать целое событие к пользовательской функции. Затем эта функция может содержать ссылку на обработчик и убедиться, что привязан только один обработчик. Конечно, это требует, чтобы обработчик привязывался только к элементу через эту функцию. –

+1

Я не понимаю вашего объяснения, почему вы должны использовать анонимную функцию. Вот связанный с ним вопрос: http://stackoverflow.com/questions/4386300/javascript-dom-how-to-remove-all-events-of-a-dom-object – basilikum

ответ

2

используя предложение Феликси

var setSingletonEventListener = (function(element){ 
    var handlers = {}; 
    return function(evtName, func){ 
     handlers.hasOwnProperty(evtName) && element.removeEventListener(evtName, handlers[evtName]); 
     if (func) { 
      handlers[evtName] = func; 
      element.addEventListener(evtName, func); 
     } else { 
      delete handlers[evtName]; 
     } 
    }; 
})(document); 

setSingletonEventListener("custom event", function(){ 

}); 

//replaces the previous 
setSingletonEventListener("custom event", function(){ 

}); 

//removes the listener, if any 
setSingletonEventListener("custom event"); 
+0

Пробовал это, но его вызывают дважды. Возможно, я сделал что-то не так - Fiddler Link http://jsfiddle.net/NeT7W/1/ – GoodSp33d

+1

@ 2-Stroker: Исправлен код, он должен был быть 'element.removeEventListener (evtName, обработчики [evtName])'. –

0

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

+0

Может ли это использовать, но в моем случае единственной постоянной переменной будет то, что в веб-Sql DB. – GoodSp33d

0

Вот один из способов:

var singletonEventListenerFor = function (element, eventName) { 
    var callback = null; 
    element.addEventListener(eventName, function() { 
     callback && callback(); 
    }); 
    return function (set) { 
     callback = set; 
    }; 
}; 

Тестирование:

var event = document.createEvent("Event"); 
event.initEvent("customEvent", true, true); 

var listener = singletonEventListenerFor(document, "customEvent"); 

var counter = 0; 

listener(function() { 
    console.log(++counter); 
}); 

// counter === 1 
document.dispatchEvent(event); 

// Remove the listener 
listener(); 
// This shouldn't increment counter. 
document.dispatchEvent(event); 

listener(function() { 
    console.log(++counter); 
}); 

// counter === 2 
document.dispatchEvent(event); 
// counter === 3 
document.dispatchEvent(event); 

console.log('3 === ' + counter); 

http://jsfiddle.net/Dogbert/2zUZT/

API может быть улучшена путем возвращения объекта с .set(callback) и .remove() функции, вместо того, чтобы использовать одну функцию, чтобы сделать обе вещи, если хотите.

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