点击事件仅适用于第二次点击
Posted
技术标签:
【中文标题】点击事件仅适用于第二次点击【英文标题】:Click event only works on the second click 【发布时间】:2022-01-24 02:35:47 【问题描述】:希望你们一切都好,好吧..
我在做一个To Do List,我的代码有问题,这几天我一直在尝试解决,没有得到有效的结果..
如果你们和我一起测试sn-p,我敢肯定,那会更多 清晰易懂。
当我点击某个列表元素时,我的 javascript 应该更改或添加 className,并添加一个类调用 'selected'。
因为,当我单击删除按钮时,他们将删除列表中具有“已选择”类列表的所有元素。 (如您在代码中所见)
但是 className a 没有被添加到 first click 中的标签 中,如果我 click 在 /p>
元素再来一次。
我简化了我的代码,只是为了显示真正的问题: jsfiddle 链接:https://jsfiddle.net/myqrzcs2/ 但是我怎样才能让类被添加,只是在第一次点击,而不是在第二次?const textoTarefa = document.getElementById('texto-tarefa');
const criarTarefa = document.getElementById('criar-tarefa');
const listaTarefas = document.getElementById('lista-tarefas');
criarTarefa.onclick = function click()
const lista = document.createElement('li');
lista.className = 'lista';
lista.id = 'lista';
lista.tabIndex = '0';
lista.innerhtml = textoTarefa.value;
listaTarefas.appendChild(lista);
document.body.appendChild(listaTarefas);
textoTarefa.value = '';
;
const completedLine = document.querySelector('ol');
function umClick(event)
if (event.target.tagName === 'LI')
const listas = document.querySelectorAll('.lista');
listas.forEach((i) =>
i.addEventListener('click', function semNomeDois()
listas.forEach((j) => j.classList.remove('selected'));
this.classList.add('selected');
);
);
completedLine.addEventListener('click', umClick);
function removeSelected()
// teste
const listaSelected = document.querySelectorAll('.selected');
for (let i = 0; i < listaSelected.length; i += 1)
listaSelected[i].remove();
.lista:focus
background: red;
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<header>
<h1>My List</h1>
</header>
<input id='texto-tarefa' type="text" />
<button id='criar-tarefa' type="submit" onClick='click()'>Add</button>
<ol id='lista-tarefas'>
</ol>
<button id='remover-selecionado' type="submit" onClick='removeSelected()'>Remove Selected (Only One)</button>
<script src="script.js"></script>
</body>
</html>
【问题讨论】:
不太清楚你在问什么。 很抱歉,你是对的.. 问题是当我点击元素 以添加“选定”类时,不起作用,只是在我第二次点击,它是添加的类..我不知道为什么.. 欢迎来到 ***。请澄清您的问题,以使其易于理解和回答。另外,您能否尝试在多个浏览器上运行您的代码?并确认问题是浏览器特定问题还是一般问题。 好的,我现在会尝试清除更多,感谢您的反馈,并将在不同的浏览器中尝试,只需要几分钟来修复和测试。但是如果尝试使用我的列表,添加和删除它,他们会明白,如果我们这样做可能会更清楚。 我测试,问题依旧,我现在编辑。 【参考方案1】:我认为你在编程时走错了路。 以下是我的使用方式,希望对你有所启发。
const
textoTarefa = document.getElementById('texto-tarefa')
, criarTarefa = document.getElementById('criar-tarefa')
, removerSelec = document.getElementById('remover-selecionado')
, listaTarefas = document.getElementById('lista-tarefas')
;
var li_selected = null
;
textoTarefa.oninput = () =>
criarTarefa.disabled = (textoTarefa.value.trim().length ===0 )
criarTarefa.onclick = () =>
listaTarefas.appendChild( document.createElement('li')).textContent = textoTarefa.value.trim()
textoTarefa.value = ''
textoTarefa.focus()
criarTarefa.disabled = true
listaTarefas.onclick = (target) =>
if (!target.matches('li')) return
if (!!li_selected && li_selected !== target ) li_selected.classList.remove('listaSelect')
li_selected = target.classList.toggle('listaSelect') ? target : null
removerSelec.disabled = !li_selected
removerSelec.onclick = () =>
listaTarefas.removeChild(li_selected)
li_selected = null
removerSelec.disabled = true
.listaSelect
background: #ff0000c4;
ol#lista-tarefas
cursor : pointer
<input id='texto-tarefa' type="text" value="">
<button id='criar-tarefa' disabled>Add</button>
<button id='remover-selecionado' disabled>Remove Selected</button>
<ol id='lista-tarefas'></ol>
【讨论】:
【参考方案2】:您不必要地为列表中的每个项目添加事件侦听器。
您可以在此处查看更新的小提琴:https://jsfiddle.net/msa9v2nf/
由于您已经在检查单击了哪个目标元素,因此无需为列表中的每个子项添加单独的侦听器。
我更新了umClick
函数:
function umClick(event)
if (event.target.tagName === 'LI')
const listas = document.querySelectorAll('.lista');
listas.forEach((i) =>
listas.forEach((j) => j.classList.remove('selected'));
event.target.classList.add('selected');
);
【讨论】:
【参考方案3】:问题是您调用函数umClick
并调用函数在同一函数umClick
中的click event
中添加.selected
。
点击事件completedLine.addEventListener('click', umClick);
发生在i.addEventListener('click', function semNomeDois()
事件之前。这就是为什么您需要第一次点击ol
标签。
要解决此问题,您有多种选择:
-
您可以调用
mousedown
,而不是在ol
标记上调用click
事件,这发生在click
事件之前。
在创建时调用li
元素的点击事件,这需要一个新函数。
根据 Vektor 的回答,您可以删除第一个 click
事件中不必要的 click
事件。
另外,我在 .selected
类上做了红色突出显示,而不是 :focus
,只是为了在选择项目时清楚。
.selected
background: red;
第一个解决方案
const textoTarefa = document.getElementById('texto-tarefa');
const criarTarefa = document.getElementById('criar-tarefa');
const listaTarefas = document.getElementById('lista-tarefas');
criarTarefa.onclick = function click()
const lista = document.createElement('li');
lista.className = 'lista';
lista.id = 'lista';
lista.tabIndex = '0';
lista.innerHTML = textoTarefa.value;
listaTarefas.appendChild(lista);
document.body.appendChild(listaTarefas);
textoTarefa.value = '';
;
const completedLine = document.querySelector('ol');
function umClick(event)
if (event.target.tagName === 'LI')
const listas = document.querySelectorAll('.lista');
listas.forEach((i) =>
i.addEventListener('click', function semNomeDois()
listas.forEach((j) =>
if(j != event.target)
j.classList.remove('selected');
);
this.classList.add('selected');
);
);
completedLine.addEventListener('mousedown', umClick);
function removeSelected()
// teste
const listaSelected = document.querySelectorAll('.selected');
for (let i = 0; i < listaSelected.length; i += 1)
listaSelected[i].remove();
.selected
background: red;
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<header>
<h1>My List</h1>
</header>
<input id='texto-tarefa' type="text" />
<button id='criar-tarefa' type="submit" onClick='click()'>Add</button>
<ol id='lista-tarefas'>
</ol>
<button id='remover-selecionado' type="submit" onClick='removeSelected()'>Remove Selected (Only One)</button>
<script src="script.js"></script>
</body>
</html>
第二种解决方案
const textoTarefa = document.getElementById('texto-tarefa');
const criarTarefa = document.getElementById('criar-tarefa');
const listaTarefas = document.getElementById('lista-tarefas');
criarTarefa.onclick = function click()
const lista = document.createElement('li');
lista.className = 'lista';
lista.id = 'lista';
lista.tabIndex = '0';
lista.innerHTML = textoTarefa.value;
listaTarefas.appendChild(lista);
lista.addEventListener('click',function()
itemClick(this);
);
document.body.appendChild(listaTarefas);
textoTarefa.value = '';
;
function itemClick(item)
const listas = document.querySelectorAll('.lista');
listas.forEach((j) =>j.classList.remove('selected'));
item.classList.add('selected');
function removeSelected()
// teste
const listaSelected = document.querySelectorAll('.selected');
for (let i = 0; i < listaSelected.length; i += 1)
listaSelected[i].remove();
.selected
background: red;
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<header>
<h1>My List</h1>
</header>
<input id='texto-tarefa' type="text" />
<button id='criar-tarefa' type="submit" onClick='click()'>Add</button>
<ol id='lista-tarefas'>
</ol>
<button id='remover-selecionado' type="submit" onClick='removeSelected()'>Remove Selected (Only One)</button>
<script src="script.js"></script>
</body>
</html>
【讨论】:
谢谢你,天哪,它有效。我会花点时间研究你的代码,不要再犯这个错误,非常感谢。 我已经编辑了答案,以明确解决问题的原因。 这么多的代码,这么少的事…… @MisterJojo *** 不是为解释代码制作的吗?我只是想详细解释一下:) 这很好,但它也适用于代码审查【参考方案4】:我不完全理解你的问题,但是, 如果要在选择项目时添加样式,只需将样式添加到
.selected
如果你想获得焦点,并在没有焦点时移除类,你可以添加一个事件监听器来控制它。
【讨论】:
发生了什么,当我单击元素 添加“已选择”类时,一开始不起作用,只是在我第二次单击时,添加的类..我不知道为什么..以上是关于点击事件仅适用于第二次点击的主要内容,如果未能解决你的问题,请参考以下文章