点击事件仅适用于第二次点击

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

如果你想获得焦点,并在没有焦点时移除类,你可以添加一个事件监听器来控制它。

【讨论】:

发生了什么,当我单击元素 添加“已选择”类时,一开始不起作用,只是在我第二次单击时,添加的类..我不知道为什么..

以上是关于点击事件仅适用于第二次点击的主要内容,如果未能解决你的问题,请参考以下文章

jQuery onclick仅适用于第二次点击

Vue.js 组件导航活动类仅适用于第二次点击

添加事件(jquery)

DOM 只注册一键点击事件移除元素

文本框事件仅触发第二次

jquery hover 仅适用于点击事件?