没有在以下js代码中添加Eventlisteners

问题描述 投票:1回答:2

我正在构建一个todo应用程序,我使用javascript动态生成任务。[]每当我点击添加按钮时,我都会从js生成以下等效的html:

<div class="row datasection">
  <div class="todo">
    <div class="databox col s6 offset-s1 waves-effect">
      <p class="checkglyph1 checkglyph2">Task no 1</p>
      <a>
        <i class="material-icons checkglyph checkglyph1 checkglyph2 glyphcolor">check</i>
      </a>
    </div>
  </div>
</div>

现在我想要的是每当我点击创建的任务上的事件时它应该变成黄色的颜色。我已经写了代码。但是,只有在创建了一个任务时它才能正常工作。如果有多个,那么最后一个任务运行良好但第一个上的actionlistener似乎不起作用。我无法弄清楚代码在哪里破坏。

var glyph= document.querySelectorAll(".glyphcolor");

for (var i = 0; i < glyph.length; i++) {
    glyph[i].addEventListener('click', function(event) {
        this.classList.toggle("checkglyph1");
    });
}

实际的片段

//declaration
    var calendardata = document.getElementById('date1');
    var addbutton = document.querySelector('.addbutton');
    var todo = document.querySelector('.todo');
    addbutton.addEventListener('click', function() {

/* body to return the html */

      if (data.value) {
        var newdiv = document.createElement("div"); // Create a <button> element
        newdiv.classList.add("databox", "col", "s6", "waves-effect");
        //console.log(newdiv);
        todo.appendChild(newdiv);
        //console.log(newdiv.parentNode);
        var newpar = document.createElement("p");
        newpar.classList.add("checkglyph1", "checkglyph2");
        var node = document.createTextNode(data.value + "." + "      " + 
        calendardata.value);
        var newa = document.createElement("a");
        newdiv.appendChild(newa)
        var newglyph = document.createElement("i");
        newglyph.classList.add("material-icons", "checkglyph", "checkglyph1", 
        "checkglyph2", "glyphcolor");
        var node1 = document.createTextNode("check");
        newa.appendChild(newglyph);
        newglyph.append(node1);
        newpar.appendChild(node);
        newdiv.appendChild(newpar);
        data.value = "";
        calendardata.value = "";
        created = true;
      //  console.log("before glyh created");

        //code to perform action on the click of the tick symbol

        var glyph = document.querySelectorAll(".glyphcolor");
        var par = document.getElementsByClassName('checkglyph2');
        for (var i = 0; i < glyph.length; i++) {
    //console.log("Inside the loop");
    glyph[i].addEventListener('click', function.bind(event) {
        this.classList.toggle("checkglyph1");
        //console.log('Inside the click');
        //console.log(i);
    });


}   

      }
    })
javascript html css
2个回答
1
投票

您的代码的问题在于,每次单击“.addbutton”时,您将浏览DOM中的所有“.glyphcolor”元素并添加新的onclick事件侦听器。创建的最后一个将起作用,但其他人将重复多个事件监听器(是的,这是可能的)。因此,当您单击一个有两个事件的元素告诉它切换“checkglyph1”类时,它会执行两次。当然,它根本不会改变。您可以很容易地看到这种情况发生,因为页面中的所有奇数元素都必须工作(它们将按奇数次切换类),而偶数元素则不能。

当您在页面上创建事件侦听器时,可以通过直接在元素上添加事件侦听器来更正此问题。下面的代码必须正常工作:

//declaration
var calendardata = document.getElementById('date1');
var addbutton = document.querySelector('.addbutton');
var todo = document.querySelector('.todo');

addbutton.addEventListener('click', function() {
  if (data.value) {
    var newdiv = document.createElement("div"); // Create a <button> element
    newdiv.classList.add("databox", "col", "s6", "waves-effect");
    //console.log(newdiv);
    todo.appendChild(newdiv);
    //console.log(newdiv.parentNode);
    var newpar = document.createElement("p");
    newpar.classList.add("checkglyph1", "checkglyph2");
    var node = document.createTextNode(data.value + "." + "      " + 
    calendardata.value);
    var newa = document.createElement("a");
    newdiv.appendChild(newa)
    var newglyph = document.createElement("i");
    newglyph.classList.add("material-icons", "checkglyph", "checkglyph1", 
    "checkglyph2", "glyphcolor");
    var node1 = document.createTextNode("check");
    newa.appendChild(newglyph);
    newglyph.append(node1);
    newpar.appendChild(node);
    newdiv.appendChild(newpar);
    data.value = "";
    calendardata.value = "";
    created = true;

    newglyph.addEventListener('click', function(event) {
        event.preventDefault(); // Just to prevent non desired effects of click

        newglyph.classList.toggle('checkglyph1');
    }
   }
 }

只是一点点澄清:您不需要在实际代码中使用“绑定”。

glyph[i].addEventListener('click', function.bind(event) { // just type function(event)
   this.classList.toggle('checkglyph1');...

2
投票

发生了什么,当他们创建其他任务时,他们没有被收集在节点集合中,因此他们没有事件监听器。您可以做的是将事件侦听器添加到容器并更改单击的项目:

document.querySelector('ul').addEventListener('click', changeClass);
document.querySelector('#button').addEventListener('click', addLi);

function changeClass(e){
  e.target.closest('li').classList.toggle('checkglyph1');
}

function addLi(e){
  const new_li = document.createElement('li');
  new_li.textContent = document.querySelectorAll('li').length + 1;
  new_li.classList.add('checkglyph1');
  document.querySelector('ul').appendChild(new_li);
}
li:not(.checkglyph1) {
  background: #f00;
}
<button id="button">Add li</button>
<ul>
  <li class="checkglyph1">1</li>
  <li class="checkglyph1">2</li>
  <li class="checkglyph1 red">3</li>
  <li class="checkglyph1">4</li>
  <li class="checkglyph1">5</li>
  <li class="checkglyph1">6</li>
  <li class="checkglyph1">7</li>
  <li class="checkglyph1">8</li>
  <li class="checkglyph1">9</li>
  <li class="checkglyph1">10</li>
</ul>
© www.soinside.com 2019 - 2024. All rights reserved.