Функция обратного вызова для каждого заданного события на веб-странице

#javascript

Вопрос:

Например, у меня есть анимация, я воспроизводю ее с помощью setInterval. Когда происходит событие, которое я ранее установил на веб-странице, я хочу, чтобы была запущена функция обратного вызова для вызова clearInterval. Любопытно, есть ли способ настроить такую функцию обратного вызова для всех событий, существующих на веб-странице. Потому что в противном случае мне придется просмотреть каждое событие, которое я установил ранее. В виде кода меня интересует что-то подобное:

 const i = setInterval(function() {  //do something }, 50);  AdditionalCallbackForEveryEventSet(function() {  clearInterval(i); });  

Ответ №1:

У меня был аналогичный опыт, но я хотел очистить всех слушателей, когда пользовательский компонент был удален из DOM (следовательно, я использовал .call() ). Это может быть немного слишком сложно для вас, но я хочу отметить, что вам нужно создать функциональность, которую вам нужно использовать, вместо того, чтобы напрямую устанавливать интервал/прослушиватели setInterval/addEventListener .

Некоторые Примеры

Добавить слушателя
FXListenerBehavior.setListener.call(window, 'aKeyToDiffentiate', functionName);

Удалить прослушиватель
FXListenerBehavior.clearListener.call(window, 'aKeyToDiffentiate', functionName);

Добавить интервал
const TIME_IN_MILLIS = 2000;
FXListenerBehavior.setInterval.call(window, 'aKeyToDiffentiate', functionName, TIME_IN_MILLIS);

Удалите все интервалы и прослушиватели
FXListenerBehavior.clearAllIntervals.call(window);

Выведите все прослушиватели и интервалы
Приятно при отладке.
FXListenerBehavior.printAll.call(window);

Удалите всех слушателей и интервалы
FXListenerBehavior.clearAll.call(window);

 FXListenerBehavior = {   /* === SET AND UPDATE === */   /**  * @description sets a listener  * @param {String} name any descriptive name  * @param {function} method the function to be run with the listener  * @param {setOnElement} Boolean if the listener should be set on the element or default to window  * @return {Boolean} true if set, false if listener already exist  */  setListener: function(name, method, setOnElement) {  if (FXListenerBehavior._alreadyExist.call(this, name)) {  var elementName = FXListenerBehavior._getElementName.call(this);   console.warn(elementName   '"'   name   '" already exist. Use updateListener() if you're unsure if the listener exists');   return false;  }   return FXListenerBehavior._setListener.call(this, name, method, setOnElement);  },   /**  * @description sets an interval  * @param {String} name any descriptive name  * @param {function} method the method to be repeated  * @param {Integer} time repeats method after this many milliseconds  * @return {Boolean} true if set, false if listener already exist  */  setInterval: function(name, method, time) {  if (FXListenerBehavior._alreadyExist.call(this, name)) {  var elementName = FXListenerBehavior._getElementName.call(this);   console.warn(elementName   '"'   name   '" already exist. Use updateInterval() if you're unsure if the interval exists');   return false;  }   return FXListenerBehavior._setInterval.call(this, name, method, time);  },   /**  * @description replaces a listener or interval, or creates one if it doesn't exist  * @param {String} name any descriptive name  * @param {function} method the method to be run  * @param {Integer} time repeats method after this many milliseconds (only for intervals)  * @return {Boolean} always true  */  update: function(name, method, time) {  if (time gt; 0) {  return FXListenerBehavior.updateInterval.call(this, name, method, time);  } else {  var setOnElement = time;  return FXListenerBehavior.updateListener.call(this, name, method, setOnElement);  }  },   updateListener: function(name, method, setOnElement) {  FXListenerBehavior.clearListener.call(this, name);  return FXListenerBehavior._setListener.call(this, name, method, setOnElement);  },   updateInterval: function(name, method, time) {  FXListenerBehavior.clearInterval.call(this, name);  return FXListenerBehavior._setInterval.call(this, name, method, time);  },   _setListener: function(name, method, setOnElement) {  if (name == undefined || method == undefined) {  traceDebug('name or method is undefined', name, method)  return  }   this._listenersAndIntervals[name] = method;   if (setOnElement) {  this.addEventListener(name, method, {  'passive': true  });  } else {  window.addEventListener(name, method, {  'passive': true  });  }   return true;  },   _setInterval: function(name, method, time) {  if (name == undefined || method == undefined) {  traceDebug('name or method is undefined', name, method)  return  }   var intervalId = setInterval(method, time);  this._listenersAndIntervals[name] = intervalId;  return true;  },   _alreadyExist: function(name) {  if (typeof this._listenersAndIntervals === 'undefined') {  this._listenersAndIntervals = {};  }   if (this._listenersAndIntervals[name]) {  return true;  }   return false;  },    /* === GET AND PRINT === */    getAll: function() {  return Object.keys(this._listenersAndIntervals);  },   printAll: function() {  if (this._listenersAndIntervals) {  var isPolymer2Element = this.is == 'function';  let elementName = (isPolymer2Element) ? this.is() : this.is;   console.info("All listeners and intervals for "   elementName   ":n"   JSON.stringify(Object.keys(this._listenersAndIntervals)));  }  },    /* === CLEAR === */    /**  * @description clears a listener  * @param {String} name any descriptive name, previously set with setListener  */  clearListener: function(name) {  if (FXListenerBehavior._alreadyExist.call(this, name)) {  window.removeEventListener(name, this._listenersAndIntervals[name])  delete this._listenersAndIntervals[name];  }  },   /**  * @description clears an interval  * @param {String} name any descriptive name, previously set with setInterval  */  clearInterval: function(name) {  if (FXListenerBehavior._alreadyExist.call(this, name)) {  clearInterval(this._listenersAndIntervals[name]);  delete this._listenersAndIntervals[name];  }  },   clearAllListeners: function() {  FXListenerBehavior._clear.call(this, 'listener');  },   clearAllIntervals: function() {  FXListenerBehavior._clear.call(this, 'interval');  },   clearAll: function(print) {  if (print) {  FXListenerBehavior.printAll.call(this)  }   FXListenerBehavior._clear.call(this);   if (print) {  FXListenerBehavior.printAll.call(this)  }  },   _clear: function(listenerOrInterval) {  if (typeof this._listenersAndIntervals === 'object') {   var keys = Object.keys(this._listenersAndIntervals);   for (var i = keys.length - 1; i gt;= 0; i--) {  if (typeof this._listenersAndIntervals[keys[i]] === 'function' amp;amp; listenerOrInterval !== 'interval') {  FXListenerBehavior.clearListener.call(this, keys[i]);  } else if (typeof this._listenersAndIntervals[keys[i]] === 'number' amp;amp; listenerOrInterval !== 'listener') {  FXListenerBehavior.clearInterval.call(this, keys[i]);  } else {  var elementName = FXListenerBehavior._getElementName.call(this);   console.warn(elementName   keys[i]   ' is not a '   (listenerOrInterval || 'listener'));  }  }   }  },   _getElementName: function() {  var elementName = this.is ||  this.tagName || this.nodeName;   if (!elementName) {  traceDebug('FXListenerBehavior lacks element information');  }   return (this) ? elementName   ': ' : '';  } }