对象字面量中的 removeEventListener
removeEventListener in object literal
我正在努力处理对象文字中的 removeEventListener
。
我有一个对象,当用户在网站上使用 tab 键时,它处理添加和删除自定义大纲。
const OUTLINE = {
enableOutline: function () {
if (event.key === 'Tab' || (event.shiftKey && event.key === 'Tab')) {
document.addEventListener('focusin', () => this.showOutline());
}
},
showOutline: function () {
this.showLogoOutline(event);
},
showLogoOutline: function () {
if (event.target === this.logo) {
this.logo.classList.add('logo_outline');
}
}
};
document.addEventListener('keydown', () => OUTLINE.enableOutline(event));
同一对象包含删除轮廓的方法,但未成功尝试删除 EventListener
。
const OUTLINE = {
hideOutline: function () {
this.hideLogoOutline();
// BELOW DOESN'T WORK
document.removeEventListener('focusin', this.showOutline);
},
hideLogoOutline: function () {
if (this.logo.classList.contains('logo_outline')) {
this.logo.classList.remove('logo_outline');
}
}
};
document.addEventListener('mousedown', () => OUTLINE.hideOutline());
正如 @Mike 'Pomax' Kamermans 在评论中提到的,每次您说 () => aFunction()
,您都在创建一个全新的函数。只需传入 aFunction
.
之类的原始函数
您似乎也没有正确传递 event
变量,我已经在下面的代码块中修复了这个问题。
const OUTLINE = {
enableOutline: function (event) {
if (event.key === 'Tab' || (event.shiftKey && event.key === 'Tab')) {
document.addEventListener('focusin', this.showOutline);
}
},
showOutline: function (event) {
this.showLogoOutline(event);
},
showLogoOutline: function (event) {
if (event.target === this.logo) {
this.logo.classList.add('logo_outline');
}
},
hideOutline: function () {
this.hideLogoOutline();
document.removeEventListener('focusin', this.showOutline);
},
hideLogoOutline: function () {
if (this.logo.classList.contains('logo_outline')) {
this.logo.classList.remove('logo_outline');
}
}
};
document.addEventListener('keydown', OUTLINE.enableOutline);
document.addEventListener('mousedown', OUTLINE.hideOutline);
首先:永远不要超载制表键(或任何在所有浏览器中具有通用行为的键)。 Tab
被浏览器用来在 tabIndexable 元素中导航,像这样的代码“捕获”了 tab 键。不酷。尤其不适合不会使用鼠标的人。 特别是如果这“只适合你”或“只适合[你认识的人不属于该类别]”,养成不超负荷的习惯内置行为,因为这样你就不会在确实重要的时候写出糟糕的代码。
话虽如此,您实际上并没有删除添加的侦听器。函数 () => OUTLINE.hideOutline()
是一个新函数,作用域为声明上下文(与使用 function() { ...}
时获得的执行上下文相反),因此指向与 [=16 完全不同的东西=] 指向.
删除侦听器时不会进行任何类型的搜索或匹配,它只能删除您之前告诉它添加的 exactly the same thing(即它必须具有相同的事件名称、相同的函数句柄和如果您指定了相同的优先级标志)。
因为这是一个单例对象原语(例如没有有意义的this
),不要使用this
,直接使用它的const
名称来引用它自己,所以你可以通过直接引用来添加和删除它的功能:
const OUTLINE = {
...
enableOutline: function(event) {
const { key } = event;
if (key.toLowerCase() === `f`) {
document.addEventListener('focusin', OUTLINE.showOutline);
}
}
hideOutline: function(_event) {
document.removeEventListener('focusin', OUTLINE.showOutline);
},
};
当然,如果您要进行设置,需要大量添加和删除事件侦听器,请编写一个简单的事件管理器。例如。从这样的东西开始,然后根据需要对其进行自定义。
class EventManager {
constructor() {
this.events = {};
}
listen(target, evtName, handler) {
if (!this.events[evtName]) this.events[evtName] = [];
const evtList= this.events[evtName];
const position = this.events[evtName].length;
const entry = { target, handler, removed:false, remove: () => {
// removeEventListener always returns undefined
evtList[position] = target.removeEventListener(evtName, handler);
entry.removed = true;
}});
target.addEventListener(evtName, handler);
this.events[evtName].push(entry);
return entry;
}
forget(target, evtName, handler=false) {
const evtList = this.events[evtName];
evtList
.filter(e => (e.target===target && (handler ? e.handler===handler : true)))
.forEach(e => e.remove())
}
}
const Events = new EventManager();
export default Events
这会将您的代码变成如下所示:
import Events from "globalManager";
const OUTLINE = {
...
enableOutline: function(event) {
const { key } = event;
if (key.toLowerCase() === `f` && !OUTLINE.listener) {
OUTLINE.listener = Events.listen(document, `focusin`, OUTLINE.showOutline);
}
}
hideOutline: function() {
if (OUTLINE.listener) {
OUTLINE.listener = OUTLINE.listener.remove();
}
},
};
我正在努力处理对象文字中的 removeEventListener
。
我有一个对象,当用户在网站上使用 tab 键时,它处理添加和删除自定义大纲。
const OUTLINE = {
enableOutline: function () {
if (event.key === 'Tab' || (event.shiftKey && event.key === 'Tab')) {
document.addEventListener('focusin', () => this.showOutline());
}
},
showOutline: function () {
this.showLogoOutline(event);
},
showLogoOutline: function () {
if (event.target === this.logo) {
this.logo.classList.add('logo_outline');
}
}
};
document.addEventListener('keydown', () => OUTLINE.enableOutline(event));
同一对象包含删除轮廓的方法,但未成功尝试删除 EventListener
。
const OUTLINE = {
hideOutline: function () {
this.hideLogoOutline();
// BELOW DOESN'T WORK
document.removeEventListener('focusin', this.showOutline);
},
hideLogoOutline: function () {
if (this.logo.classList.contains('logo_outline')) {
this.logo.classList.remove('logo_outline');
}
}
};
document.addEventListener('mousedown', () => OUTLINE.hideOutline());
正如 @Mike 'Pomax' Kamermans 在评论中提到的,每次您说 () => aFunction()
,您都在创建一个全新的函数。只需传入 aFunction
.
您似乎也没有正确传递 event
变量,我已经在下面的代码块中修复了这个问题。
const OUTLINE = {
enableOutline: function (event) {
if (event.key === 'Tab' || (event.shiftKey && event.key === 'Tab')) {
document.addEventListener('focusin', this.showOutline);
}
},
showOutline: function (event) {
this.showLogoOutline(event);
},
showLogoOutline: function (event) {
if (event.target === this.logo) {
this.logo.classList.add('logo_outline');
}
},
hideOutline: function () {
this.hideLogoOutline();
document.removeEventListener('focusin', this.showOutline);
},
hideLogoOutline: function () {
if (this.logo.classList.contains('logo_outline')) {
this.logo.classList.remove('logo_outline');
}
}
};
document.addEventListener('keydown', OUTLINE.enableOutline);
document.addEventListener('mousedown', OUTLINE.hideOutline);
首先:永远不要超载制表键(或任何在所有浏览器中具有通用行为的键)。 Tab
被浏览器用来在 tabIndexable 元素中导航,像这样的代码“捕获”了 tab 键。不酷。尤其不适合不会使用鼠标的人。 特别是如果这“只适合你”或“只适合[你认识的人不属于该类别]”,养成不超负荷的习惯内置行为,因为这样你就不会在确实重要的时候写出糟糕的代码。
话虽如此,您实际上并没有删除添加的侦听器。函数 () => OUTLINE.hideOutline()
是一个新函数,作用域为声明上下文(与使用 function() { ...}
时获得的执行上下文相反),因此指向与 [=16 完全不同的东西=] 指向.
删除侦听器时不会进行任何类型的搜索或匹配,它只能删除您之前告诉它添加的 exactly the same thing(即它必须具有相同的事件名称、相同的函数句柄和如果您指定了相同的优先级标志)。
因为这是一个单例对象原语(例如没有有意义的this
),不要使用this
,直接使用它的const
名称来引用它自己,所以你可以通过直接引用来添加和删除它的功能:
const OUTLINE = {
...
enableOutline: function(event) {
const { key } = event;
if (key.toLowerCase() === `f`) {
document.addEventListener('focusin', OUTLINE.showOutline);
}
}
hideOutline: function(_event) {
document.removeEventListener('focusin', OUTLINE.showOutline);
},
};
当然,如果您要进行设置,需要大量添加和删除事件侦听器,请编写一个简单的事件管理器。例如。从这样的东西开始,然后根据需要对其进行自定义。
class EventManager {
constructor() {
this.events = {};
}
listen(target, evtName, handler) {
if (!this.events[evtName]) this.events[evtName] = [];
const evtList= this.events[evtName];
const position = this.events[evtName].length;
const entry = { target, handler, removed:false, remove: () => {
// removeEventListener always returns undefined
evtList[position] = target.removeEventListener(evtName, handler);
entry.removed = true;
}});
target.addEventListener(evtName, handler);
this.events[evtName].push(entry);
return entry;
}
forget(target, evtName, handler=false) {
const evtList = this.events[evtName];
evtList
.filter(e => (e.target===target && (handler ? e.handler===handler : true)))
.forEach(e => e.remove())
}
}
const Events = new EventManager();
export default Events
这会将您的代码变成如下所示:
import Events from "globalManager";
const OUTLINE = {
...
enableOutline: function(event) {
const { key } = event;
if (key.toLowerCase() === `f` && !OUTLINE.listener) {
OUTLINE.listener = Events.listen(document, `focusin`, OUTLINE.showOutline);
}
}
hideOutline: function() {
if (OUTLINE.listener) {
OUTLINE.listener = OUTLINE.listener.remove();
}
},
};