javascript - 网页上每个设置事件的回调函数
问题描述
例如,我有一个动画,我用 setInterval 播放它。当我之前在网页上设置的事件发生时,我希望触发一个回调函数来调用 clearInterval。好奇是否有任何方法可以为网页中存在的所有事件设置这样的回调函数。因为否则我将不得不检查我之前设置的每个事件。以代码的形式,我对类似的东西感兴趣:
const i = setInterval(function() {
//do something
}, 50);
AdditionalCallbackForEveryEventSet(function() {
clearInterval(i);
});
解决方案
我也有类似的经历,但想在从 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 > 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 >= 0; i--) {
if (typeof this._listenersAndIntervals[keys[i]] === 'function' && listenerOrInterval !== 'interval') {
FXListenerBehavior.clearListener.call(this, keys[i]);
} else if (typeof this._listenersAndIntervals[keys[i]] === 'number' && 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 + ': ' : '';
}
}
推荐阅读
- http - 保持活动请求 _change 连续供稿
- javascript - HTMLImageElement onclick
- rust - 在循环中将两个元素添加到向量的函数的功能等效项
- c - 像 linux 命令一样的 C 行对齐
- c++ - 来自三个 XYZ 向量的 vtkStructuredGrid 的 VTK C++ 设置点
- react-router - 如何在反应路由器中加载进入下一个路由之前避免闪烁?
- python - Python:检查最后一个字符串的函数
- android - Android ClassCastException同时在另一个片段中实现TimePickerDialog.OnTimeSetListener接口的onTimeSet方法
- javascript - 如何在javascript函数中为参数的特定默认值设置值
- mysql - minikube部署mysql失败...镜像拉取失败..ubuntu环境