像 jQuery 中那样的命名空间香草 JavaScript 事件

Namespace vanilla JavaScript events like in jQuery

在jQuery中,当您设置事件时,您可以为其命名空间。这意味着(如果你愿意的话)你可以有多个调整大小 window 事件,例如,并且能够单独解除绑定它们而不解除绑定该选择器上的所有事件。

jQuery 命名空间示例:

$(window).on('scroll.myScrollNamespace, function() ...

我想知道如何在普通 JavaScript 中创建命名空间。这显然行不通:

window.addEventListener('resize.myScrollNamespace', function() ...

如果不是匿名函数:

window.addEventListener('resize', function () {...});

您使用命名函数:

window.addEventListener('resize', function myScroll() {...});

那么您也许可以使用:

window.removeEventListener('resize', myScroll);

确保您有 myScroll 范围。当你在不同的地方删除监听器而不是添加它们时,也许你应该在一些外部范围内定义你的函数并在 addEventListener 中使用它们的名称,就像在 removeEventListener:[=19 中一样=]

function myScroll() {
  // ...
}

window.addEventListener('resize', myScroll);

window.removeEventListener('resize', myScroll);

如果您希望能够一次删除多个侦听器,则必须将它们存储在某个数组中,并为其每个元素调用 removeEventListener。

请参阅 EventTarget.removeEventListener() 文档。

由于@rsp 的回答正确地解决了解除绑定正确处理程序的问题,它并没有真正回答命名空间的问题。 要处理这个问题,您需要像这样进行更多编码:

function on(elm, evtName, handler) {
  evtName.split('.').reduce(function(evtPart, evt) {
    evt = evt ? evt +'.'+ evtPart : evtPart;
    elm.addEventListener(evt, handler, true);
    return evt;
  }, '');
}

function off(elm, evtName, handler) {
  evtName.split('.').reduce(function(evtPart, evt) {
    evt = evt ? evt +'.'+ evtPart : evtPart;
    elm.removeEventListener(evt, handler, true);
    return evt;
  }, '');
}

// Your handler
function onScroll(e) { ... }

// To bind it
on(window, 'scroll.myScrollNamespace', onScroll);

// To unbind it
off(window, 'scroll.myScrollNamespace', onScroll);

所以总结一下:这实际上设置了几个事件侦听器 - 一个用于命名空间的每个部分。遗憾的是,此功能不受原生支持,但如您所见,它可以相对简单地实现。请注意,即使此脚本支持深层命名空间(例如 scroll.parent.child),它也会绑定很多事件侦听器(在本例中为 3 个),因此是不可取的。

您可能会做得更好,但这已经完成了。