繁体   English   中英

删除事件监听器无法正常工作

[英]Remove event listener doesn't work as it should

我只是尝试将addEventListener和removeEventListener添加到元素,但不会删除。

我想问题可能出在参数上,但是我用它们来遵循DRY。 因此,我可以像nextSection.addEventListener('mouseover',showContent(event,nextSection))等那样简单地重用它,以此类推,所以我不需要任何if语句或类似的东西。

*编辑*

我还制作了一些将要使用的元素的示例。 有机会,还有更多的活动。 如果我不使用参数,将会有更多的功能。 另外,在移动设备上将有单击而不是鼠标事件,因此我需要将其删除。

据我了解,问题在于return语句。 如果我使用事件而不是参数,所以使用event.target会出现一些奇怪的错误。

const loginSection = document.querySelector('#js-login-section');
const searchSection = document.querySelector('#js-search-section');
const shoppingBagSection = document.querySelector('#js-shopping-bag-section');
const wishlistSection = document.querySelector('#js-wishlist-section');

function showContent(element) {
    return () => {
        const toggle = element.lastElementChild;
        toggle.style.maxHeight = toggle.scrollHeight + 'px';
    }
}

function hideContent(element) {
    return () => {
        const toggle = element.lastElementChild;
        toggle.style.maxHeight = null;
    }
}

/* Media queries - min width 992px */
loginSection.addEventListener('mouseover', showContent(loginSection));
loginSection.addEventListener('mouseout', hideContent(loginSection));
searchSection.addEventListener('mouseover', showContent(searchSection));
searchSection.addEventListener('mouseout', hideContent(searchSection));
shoppingBagSection.addEventListener('mouseover', showContent(shoppingBagSection));
shoppingBagSection.addEventListener('mouseout', hideContent(shoppingBagSection));
wishlistSection.addEventListener('mouseover', showContent(wishlistSection));
wishlistSection.addEventListener('mouseout', hideContent(wishlistSection));

/* Media queries - max width 992px */
loginSection.removeEventListener('mouseover', showContent(loginSection));
loginSection.removeEventListener('mouseout', hideContent(loginSection));
searchSection.removeEventListener('mouseover', showContent(searchSection));
searchSection.removeEventListener('mouseout', hideContent(searchSection));
shoppingBagSection.removeEventListener('mouseover', showContent(shoppingBagSection));
shoppingBagSection.removeEventListener('mouseout', hideContent(shoppingBagSection));
wishlistSection.removeEventListener('mouseover', showContent(wishlistSection));
wishlistSection.removeEventListener('mouseout', hideContent(wishlistSection));

先感谢您!

发生的是return () => {}; 每次运行时都会返回一个新函数。 因此,每次调用函数之一时,都会创建一个新的事件处理程序。

这意味着添加的处理程序与您要删除的处理程序不同。

为了解决这个问题,我将使其保持简单:

const loginSection = document.querySelector('#js-login-section');

function showContent(e)
{
  const toggle = e.currentTarget.lastElementChild;
  toggle.style.maxHeight = toggle.scrollHeight + 'px';
}

function hideContent(e)
{
  const toggle = e.currentTarget.lastElementChild;
  toggle.style.maxHeight = null;
}

loginSection.addEventListener('mouseover', showContent);
loginSection.addEventListener('mouseout', hideContent);

loginSection.removeEventListener('mouseover', showContent);
loginSection.removeEventListener('mouseout', hideContent);

我不确定您想避免重复什么,所以我不建议这样做,但是我敢肯定您会弄清楚。

const loginSection = document.querySelector('#js-login-section');

function showContent(event) {
    var element = event.target;
    return () => {
        const toggle = element.lastElementChild;
        toggle.style.maxHeight = toggle.scrollHeight + 'px';
    }
}

function hideContent(event) {
    var element = event.target;
    return () => {
        const toggle = element.lastElementChild;
        toggle.style.maxHeight = null;
    }
}

loginSection.addEventListener('mouseover', showContent);
loginSection.addEventListener('mouseout', hideContent);

loginSection.removeEventListener('mouseover', showContent);
loginSection.removeEventListener('mouseout', hideContent);

您必须在事件方法中设置函数而无需调用。 您可以从事件event.target获取的元素

在您的代码中,我发现了以下错误,

  1. 参数“事件”将始终是未定义的-事件应作为内部函数的参数使用。
  2. 您无需在此处关闭-您可以直接分配函数而无需创建内部函数,并使用event.targetthis访问元素
  3. 在实现中,您应该将addEventListener使用的处理程序引用传递给removeEventListener 因此,您应该将处理程序存储在变量中,并将其传递给addEventListenerremoveEventListener

解决方案:如果您不知道处理程序名称,则可以使用window.getEventListeners进行操作,

window.getEventListeners返回与元素关联的事件的字典。

 function removeEventListener(el, eventName) { if (!el) { throw new Error('Invalid DOM reference passed'); } const listeners = getEventListeners(el)[eventName] || []; listeners.forEach(({ listener }) => { removeEventListener(eventName, listener); }); } function removeAllEventListener(el) { if (!el) { throw new Error('Invalid DOM reference passed'); } const events = Object.entries(getEventListeners(el) || {}); events.forEach(([eventName, listeners]) => { listeners.forEach(({ listener }) => { removeEventListener(eventName, listener); }); }); } // example // remove mouseout event removeEventListener(loginSection, 'mouseout'); // remove all event listeners removeAllEventListener(loginSection); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM