首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >removeEventListener in forEach

removeEventListener in forEach
EN

Stack Overflow用户
提问于 2022-08-24 22:54:24
回答 2查看 68关注 0票数 0

朋友!

在JS中,如何在集合的所有按钮上挂起这样的处理程序,以便当单击每个按钮时,发生一些事情,并且从集合中的所有按钮中移除处理程序?我成功地实现了它,以便只从我单击的那个中删除它(而类从每个人中被删除):

代码语言:javascript
复制
document.querySelectorAll('.string').forEach((field, i, fields) => {
  const listen = () => {
    const res = document.createElement('div');
    res.textContent = field.textContent;
    document.getElementById('container').append(res);

    fields
      .forEach((field, i, fields) => {
        field.classList.remove('bright');
        field.removeEventListener('click', listen);
      });
  };

  field.addEventListener('click', listen);
});

https://codepen.io/andreymi/pen/RwMOvOq

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-25 04:14:05

您的代码无法工作,因为对每个元素重新创建了listen函数

代码语言:javascript
复制
var fields=document.querySelectorAll('.string');

const listen = () => {
  const res = document.createElement('div');
  res.textContent = this.textContent;     // <- note 'this' keyword
  document.getElementById('container').append(res);

  fields.forEach((field, i, fields) => {
    field.classList.remove('bright');
    field.removeEventListener('click', listen);
    console.log('remove',i);
  });
};

fields.forEach((field, i, fields) => {
  console.log('add',i);
  field.addEventListener('click', listen);
});
票数 0
EN

Stack Overflow用户

发布于 2022-08-24 22:59:26

与其向all添加侦听器,然后从all中移除侦听器,不如将单个侦听器添加到具有事件委托的容器元素中,然后通过再次引用函数名轻松地删除该侦听器如何?

代码语言:javascript
复制
const buttons = document.querySelectorAll('.string');
const flex = document.querySelector('.flex');
flex.addEventListener('click', function handler(e) {
  if (!e.target.matches('.string')) {
    return;
  }
  flex.removeEventListener('click', handler);
  const res = document.createElement('div');
  res.textContent = e.target.textContent;
  document.getElementById('container').append(res);
  for (const button of buttons) {
    button.classList.remove('bright');
  }
});
代码语言:javascript
复制
.wrap {
  background: #808080;
  font-size: 2em;
}

.flex {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
  gap: 1em;
}

.string {
  display: flex;
  flex-grow: 1;
  height: 80px;
  background: #FFFFFF;
  justify-content: center;
  align-items: center;
  font-size: 1em;
}

.bright {
  background: #58afd1;
}
代码语言:javascript
复制
<body class="wrap">
  <div class="flex">
    <button type='button' class="string bright">1</button>
    <button type='button' class="string bright">2</button>
    <button type='button' class="string bright">3</button>
    <button type='button' class="string bright">4</button>
    <button type='button' class="string bright">5</button>
  </div>
  <div id='container'></div>
</body>

或者让按钮从容器中继承它们的样式。

代码语言:javascript
复制
const buttons = document.querySelectorAll('.string');
const flex = document.querySelector('.flex');
flex.addEventListener('click', function handler(e) {
  if (!e.target.matches('.string')) {
    return;
  }
  flex.removeEventListener('click', handler);
  const res = document.createElement('div');
  res.textContent = e.target.textContent;
  document.getElementById('container').append(res);
  flex.classList.remove('bright');
});
代码语言:javascript
复制
.wrap {
  background: #808080;
  font-size: 2em;
}

.flex {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
  gap: 1em;
}

.string {
  display: flex;
  flex-grow: 1;
  height: 80px;
  background: #FFFFFF;
  justify-content: center;
  align-items: center;
  font-size: 1em;
}

.bright .string {
  background: #58afd1;
}
代码语言:javascript
复制
<body class="wrap">
  <div class="flex bright">
    <button type='button' class="string bright">1</button>
    <button type='button' class="string bright">2</button>
    <button type='button' class="string bright">3</button>
    <button type='button' class="string bright">4</button>
    <button type='button' class="string bright">5</button>
  </div>
  <div id='container'></div>
</body>

这适用于您问题中的代码,但是如果您实际使用的代码与问题中的代码不匹配,那么:

如果您的按钮有子元素,则目标可能是这些子元素之一,而不是其中的一个,因此要检查单击的元素是否为按钮的后代,除上述之外,还可以更改为e.target.closest('.string')

  • If,,您可能有一个.string元素,它是.flex的容器,单击不在按钮上的.flex将被注册。如果您实际使用的HTML具有这种特性,那么只通过搜索带有.string.flex容器的后代来检查.contains是否是后代。从.flex容器

开始

代码语言:javascript
复制
const buttons = document.querySelectorAll('.string');
const flex = document.querySelector('.flex');
flex.addEventListener('click', function handler(e) {
  if (!flex.contains(e.target.closest('.string'))) {
    return;
  }
  flex.removeEventListener('click', handler);
  const res = document.createElement('div');
  res.textContent = e.target.textContent;
  document.getElementById('container').append(res);
  flex.classList.remove('bright');
});
代码语言:javascript
复制
.wrap {
  background: #808080;
  font-size: 2em;
}

.flex {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
  gap: 1em;
}

.string {
  display: flex;
  flex-grow: 1;
  height: 80px;
  background: #FFFFFF;
  justify-content: center;
  align-items: center;
  font-size: 1em;
}

.bright .string {
  background: #58afd1;
}
代码语言:javascript
复制
<body class="wrap">
  <div class="flex bright">
    <button type='button' class="string bright">1</button>
    <button type='button' class="string bright">2</button>
    <button type='button' class="string bright">3</button>
    <button type='button' class="string bright">4</button>
    <button type='button' class="string bright">5</button>
  </div>
  <div id='container'></div>
</body>

  • 如果您的.flex的一些子元素不是按钮,而这些元素的某些后代也有flex类,而这些.flex后代也有自己的.string后代,那么为了防止选择其中一个按钮而不是直接的子按钮的可能性,在选择最接近的.string之后,检查它的父元素是侦听器附加到的flex

F 232

代码语言:javascript
复制
const buttons = document.querySelectorAll('.string');
const flex = document.querySelector('.flex');
flex.addEventListener('click', function handler(e) {
  const button = e.target.closest('.string');
  if (!button || !button.matches('.string') || !button.parentElement === flex) {
    return;
  }
  flex.removeEventListener('click', handler);
  const res = document.createElement('div');
  res.textContent = e.target.textContent;
  document.getElementById('container').append(res);
  flex.classList.remove('bright');
});
代码语言:javascript
复制
.wrap {
  background: #808080;
  font-size: 2em;
}

.flex {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
  gap: 1em;
}

.string {
  display: flex;
  flex-grow: 1;
  height: 80px;
  background: #FFFFFF;
  justify-content: center;
  align-items: center;
  font-size: 1em;
}

.bright .string {
  background: #58afd1;
}
代码语言:javascript
复制
<body class="wrap">
  <div class="flex bright">
    <button type='button' class="string bright">1</button>
    <button type='button' class="string bright">2</button>
    <button type='button' class="string bright">3</button>
    <button type='button' class="string bright">4</button>
    <button type='button' class="string bright">5</button>
  </div>
  <div id='container'></div>
</body>

但是,如果您所拥有的HTML结构实际上是您问题中的内容,您可能会认为没有必要将事情复杂化。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73480253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档