朋友!
在JS中,如何在集合的所有按钮上挂起这样的处理程序,以便当单击每个按钮时,发生一些事情,并且从集合中的所有按钮中移除处理程序?我成功地实现了它,以便只从我单击的那个中删除它(而类从每个人中被删除):
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);
});发布于 2022-08-25 04:14:05
您的代码无法工作,因为对每个元素重新创建了listen函数
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);
});发布于 2022-08-24 22:59:26
与其向all添加侦听器,然后从all中移除侦听器,不如将单个侦听器添加到具有事件委托的容器元素中,然后通过再次引用函数名轻松地删除该侦听器如何?
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');
}
});.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;
}<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>
或者让按钮从容器中继承它们的样式。
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');
});.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;
}<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')
.string元素,它是.flex的容器,单击不在按钮上的.flex将被注册。如果您实际使用的HTML具有这种特性,那么只通过搜索带有.string的.flex容器的后代来检查.contains是否是后代。从.flex容器开始
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');
});.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;
}<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
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');
});.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;
}<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结构实际上是您问题中的内容,您可能会认为没有必要将事情复杂化。
https://stackoverflow.com/questions/73480253
复制相似问题