未删除事件监听器-点亮的元素

问题描述 投票:1回答:1

我正在研究具有两个视图的照明图像组件。

  • 单个视图,用户一次只能看到一张图像。
  • 一个网格视图,用户可以一次查看所有图像。

我可以通过按一个按钮在两个视图之间切换。当我处于“网格视图”时,我已经设置了一种选择图像的方法,当您单击它时,它将被标记为已选择。

当我在其中加载图像并切换到网格视图时,可以选择和取消选择图像而不会出现问题。如果单击返回单一视图,则返回到网格视图我无法选择任何图像。如果我第三次这样做,则可以再次选择图像。

通过调试,我发现未删除添加到映像的事件侦听器。在研究这个问题时,我尝试了几种不同的方法,但是没有运气解决这个问题。

这是我所拥有的代码,希望再次提供帮助

case 'grid':
                    this.changeViewState(buttonName);
                    imageItems.forEach((image) => {
                        image.addEventListener('click', this.selectImage.bind(this,image), false);
                    });

                    hiImage.viewMode = 'grid';
                    break;
 selectImage(image){
        let hiImage = this._getImageSection().querySelector("hi-images");
        hiImage.dispatchEvent(new CustomEvent('selected-images', {
            detail: { image: image }
        }));

        image.removeEventListener('click', this.selectImage.bind(this,image));
    }

感谢您提供任何帮助,我仍然可以通过javascript和light元素获得新的知识。

javascript lit-element
1个回答
0
投票

[当您使用.bind一个功能时,您将创建一个[[全新]功能,该功能不是先前可能已经存在的任何功能的===(即使使用相同的过程创建)。所以

this.selectImage.bind(this,image) === this.selectImage.bind(this,image)
将计算为false-===引用的每一侧的表达式

不同函数

对象。因为selectImage似乎要删除侦听器,所以一种选择是改为使用{ once: true }以确保侦听器仅运行一次:

imageItems.forEach((image) => { image.addEventListener('click', this.selectImage.bind(this, image), { once: true }); });

替代方法是将绑定函数存储在某个位置,以便以后可以用它调用removeEventListener,例如

const boundFnsByImage = new WeakMap(); // ... imageItems.forEach((image) => { const boundFn = this.selectImage.bind(this, image); boundFnsByImage.set(image, boundFn); image.addEventListener('click', boundFn); });

然后使用]进行检索>

selectImage(image){ let hiImage = this._getImageSection().querySelector("hi-images"); hiImage.dispatchEvent(new CustomEvent('selected-images', { detail: { image: image } })); const boundFn = boundFnsByImage.get(image); // <---------------------- // if you want to remove the listener when clicked: image.removeEventListener('click', boundFn); }

还请注意,除非您

want

使用捕获,否则无需将第三个useCapture参数传递给addEventListener-无论如何它将默认设置为false
如果要一次删除

all

侦听器(例如在视图切换期间),请遍历Map:
boundFnsByImage.forEach((boundFn, image) => { image.removeEventListener('click', boundFn); });
© www.soinside.com 2019 - 2024. All rights reserved.