我不知道在这种情况下如何使用ForEach

时间:2019-06-23 11:10:30

标签: javascript html css

在我的应用中,我不确定如何正确使用ForEach循环。

请输入一些文字以供输入,然后按Enter键,任务将被添加到列表中。这是addNewTask()函数。您可以通过单击编辑图标来编辑任务,但只能一次。我理解为什么,因为ForEach在addNewTask()中,所以好了,因此,如果调用了函数,则每个任务我只能编辑一次。我想我需要针对这种情况创建一个函数吗?但是我不知道如何使用它。

var editTask = document.querySelectorAll('。edit-task'); 是编辑任务图标。

如果我尝试使用例如 editTask.addEvenetListener(“ click”,function(){ ...})输出将是错误的,因为editask返回了节点列表。任何简单的解决方案?我不知道该怎么办。

JS代码从此行开始-> var editTask = document.querySelectorAll('。edit-task');

'use strict';

var todoTitle = document.querySelector('.title-input');
var todoList = document.querySelector('.todo-list');

function formatDate(date) {
    var monthNames = [
      "January", "February", "March",
      "April", "May", "June", "July",
      "August", "September", "October",
      "November", "December"
    ];
  
    var day = date.getDate();
    var monthIndex = date.getMonth();
    var year = date.getFullYear();
    var hours = date.getHours();
    var mins = date.getMinutes();
  
    return day + ' ' + monthNames[monthIndex] + ' ' + year + ', ' + hours 
+ ':' + mins;
}

function createNewTask(task) {
    var listItem = document.createElement('li');
    var textItem = document.createElement('div');
    var dateInfo = document.createElement('span');
    var icons = document.createElement('div');
    // var saveEditedTask = document.createElement('span');

var iconsClass = [
    '<i class="fas fa-tag"></i>',
    '<i class="fas fa-palette change-bgcolor"></i>',
    '<i class="fas fa-edit edit-task"></i>',
    '<i class="fas fa-check-square"></i>',
    '<i class="fas fa-times-circle delete-task"></i>'
]

iconsClass.forEach(function(icon) {

    var iconParent = document.createElement('li');
    iconParent.className = 'icon-item';
    iconParent.innerHTML = icon;
    icons.appendChild(iconParent);
    
});

dateInfo.innerText = formatDate(new Date());
dateInfo.className = 'task-date';
textItem.className = 'list-content';
icons.className = 'action-icons';
textItem.innerText = task;
listItem.className = 'list-item';
// textItem.appendChild(icons);
listItem.appendChild(textItem);
// listItem.appendChild(saveEditedTask);
listItem.appendChild(icons);
listItem.appendChild(dateInfo);

return listItem;

};

function addNewTask() {
    var listItem = createNewTask(todoTitle.value);
    todoList.appendChild(listItem);
    todoTitle.value = '';

    var deleteTask = document.querySelectorAll('.delete-task');

    deleteTask.forEach(function (icon) {
        icon.addEventListener("click", function() {
        this.closest("li.list-item").classList.add("hidden");     
        });
    });

    var editTask = document.querySelectorAll('.edit-task');

    editTask.forEach(function (icon) {
        icon.addEventListener("click", function () {
            var thisParent = 
    this.parentElement.parentElement.previousElementSibling;
            thisParent.contentEditable = true;
            thisParent.style.backgroundColor = "#efefef";
            this.classList.remove("fas", "fa-edit", "edit-task");
            this.classList.add("fas", "fa-check", "fa-2x");
        
            this.addEventListener("click", function () {
                thisParent.contentEditable = false;
                thisParent.style.backgroundColor = "#ffffff";
                this.classList.remove("fas", "fa-check", "fa-2x");
                this.classList.add("fas", "fa-edit", "edit-task");
            })
        })
    });

};

    todoTitle.addEventListener('keyup', function (event) {
        if (event.keyCode === 13 && todoTitle.value.length >= 1) {
            addNewTask();
        }
    });
* {
    -webkit-box-sizing: border-box;
            box-sizing: border-box;
}

body {
    font-family: 'Ubuntu', sans-serif;
    font-weight: 400;
    font-size: 100%;
    width: 100%;
    height: 100%;
    overflow-x: hidden;
    margin: 0;
    padding: 0;
}

#todoapp {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0px 20px;
}

input.title-input {
    -webkit-transition: all.5s;
    -webkit-transition: all .5s;
    transition: all .5s;
    display: block;
    width: 200px;
    margin: 10px 0;
    padding: 5px 15px;
    border: none;
    border-bottom: 1px solid #ccc;
    outline: none;
    position: relative;
    top: 0;
    left: 50%;
    -webkit-transform: translate(-50%, 0);
            transform: translate(-50%, 0);
    margin-bottom: 50px;
}

input.title-input:focus {
    width: 100%;
    -webkit-box-shadow: 0px 5px 20px 0px rgba(0,0,0,0.75);
            box-shadow: 0px 5px 20px 0px rgba(0,0,0,0.75);
    border-bottom: none;
    border-radius: 15px;
    font-size: 16px;
    padding: 10px 20px;
}


.todo-list {
    list-style-type: none;
    padding: 0;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
        -ms-flex-flow: row wrap;
            flex-flow: row wrap;
    -webkit-box-align: start;
        -ms-flex-align: start;
            align-items: flex-start;
    -webkit-box-pack: start;
        -ms-flex-pack: start;
            justify-content: flex-start;
}

.todo-list .list-item {
    padding: 15px;
    padding-bottom: 5px;
    background-color: #ffffff;
    border: 1px solid #e0e0e0;
    border-radius: 10px;
    color: #202124;
    margin-bottom: 10px;
    /* min-heiglist-coht: 100px; */
    width: 200px;
    position: relative;
    margin: 5px;
    -webkit-transition: all .25s;
    transition: all .25s;
}

.todo-list .list-item .bg-colors {
    width: 105px;
    height: auto;
    /* height: 100px; */
    background-color: #ffffff;
    position: absolute;
    bottom: 30px;
    left: 0;
    right: 0;
    -webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.25);
    box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.25);

    /* display: none; */
}

.todo-list .list-item .bg-colors span {
    width: 25px;
    height: 25px;
    /* background-color: #ffffff; */
    display: inline-block;
    margin: 5px;
    border-radius: 50%;
    border: 1px solid #ccc;
}

.todo-list .list-item .bg-colors span:hover {
    border-color: #000000;
}

.todo-list .list-item:hover {
    -webkit-box-shadow: 0px 5px 5px 0px rgba(0,0,0,0.25);
            box-shadow: 0px 5px 5px 0px rgba(0,0,0,0.25);
}

.todo-list .list-item:hover .action-icons {
    opacity: 1;
}

.todo-list .list-item .list-content {
    position: relative;
    min-height: 150px;
    padding: 5px;
}

.todo-list .list-item .task-date {
    font-size: 12px;
    display: block;
    text-align: right;
    padding-top: 10px;
    padding-bottom: 5px;
    border-top: 1px solid #e0e0e0;
}

.todo-list .list-item .action-icons {
    position: relative;
    bottom: 0;
    right: 0;
    left: 0;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-pack: distribute;
        justify-content: space-around;
        -webkit-box-align: center;
            -ms-flex-align: center;
                align-items: center;
    margin: 10px 0;
    /* opacity: 0; */
    -webkit-transition: all .25s;
    transition: all .25s;
}

.todo-list .list-item .action-icons .icon-item {
    display: inline-block;
    cursor: pointer;
}

.hidden { display:none !important; }

.visible { display: block !important; }

.fas.fa-check {
    color: green;
}
<link rel="stylesheet" 
href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" 
integrity="sha384- 
oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" 
crossorigin="anonymous">

<div id="todoapp">
    <input type="text" class="title-input" placeholder="Write a note..">
    <ul class="todo-list"></ul>
</div>

1 个答案:

答案 0 :(得分:1)

您的代码中存在一些逻辑错误。

在您的 addNewTask()函数内部,执行以下代码:

    var editTask = document.querySelectorAll('.edit-task');

    editTask.forEach(function (icon) {
..
}

这意味着每次添加任务时,每个先前的任务都将获得单击侦听器并重新添加所有内容。

相反,在新生成的任务中使用以下元素获取对实际上使用类 edit-task 的元素的引用:

var icon = listItem.getElementsByClassName("edit-task")[0];

这将返回一个HTML集合-它仅包含我们使用 [0] 访问的一个元素。

下一个问题是您仍然要附加点击事件监听器的方式:

   editTask.forEach(function(icon) {
     icon.addEventListener("click", function() {
       var thisParent =
         this.parentElement.parentElement.previousElementSibling;
       thisParent.contentEditable = true;
       thisParent.style.backgroundColor = "#efefef";
       this.classList.remove("fas", "fa-edit", "edit-task");
       this.classList.add("fas", "fa-check", "fa-2x");

       this.addEventListener("click", function() {
         thisParent.contentEditable = false;
         thisParent.style.backgroundColor = "#ffffff";
         this.classList.remove("fas", "fa-check", "fa-2x");
         this.classList.add("fas", "fa-edit", "edit-task");
       })
     })
   });

以上表示每次单击图标时,都添加另一个Click侦听器。这些会相互干扰,并将您的文本字段重置为不可编辑。 最好这样做: 在 createNewTask()函数内部,将div textItem 的contentEditable属性设置为false

textItem.contentEditable = false;

这样,我们可以在click事件处理程序中检查该值并采取相应的措施。如果为假,则将其设置为真,反之亦然。

  icon.addEventListener("click", function() {
    var thisParent =
      this.parentElement.parentElement.previousElementSibling;
    switch (thisParent.contentEditable) {
      case "false":
        thisParent.contentEditable = true;
        thisParent.style.backgroundColor = "#efefef";
        this.classList.remove("fas", "fa-edit", "edit-task");
        this.classList.add("fas", "fa-check", "fa-2x");
        break;
      case "true":
        thisParent.contentEditable = false;
        thisParent.style.backgroundColor = "#ffffff";
        this.classList.remove("fas", "fa-check", "fa-2x");
        this.classList.add("fas", "fa-edit", "edit-task");
        break;
    }
  });

这是完整的示例:

'use strict';

var todoTitle = document.querySelector('.title-input');
var todoList = document.querySelector('.todo-list');

function formatDate(date) {
  var monthNames = [
    "January", "February", "March",
    "April", "May", "June", "July",
    "August", "September", "October",
    "November", "December"
  ];

  var day = date.getDate();
  var monthIndex = date.getMonth();
  var year = date.getFullYear();
  var hours = date.getHours();
  var mins = date.getMinutes();

  return day + ' ' + monthNames[monthIndex] + ' ' + year + ', ' + hours +
    ':' + mins;
}

function createNewTask(task) {
  var listItem = document.createElement('li');
  var textItem = document.createElement('div');
  var dateInfo = document.createElement('span');
  var icons = document.createElement('div');
  // var saveEditedTask = document.createElement('span');

  var iconsClass = [
    '<i class="fas fa-tag"></i>',
    '<i class="fas fa-palette change-bgcolor"></i>',
    '<i class="fas fa-edit edit-task"></i>',
    '<i class="fas fa-check-square"></i>',
    '<i class="fas fa-times-circle delete-task"></i>'
  ]

  iconsClass.forEach(function(icon) {

    var iconParent = document.createElement('li');
    iconParent.className = 'icon-item';
    iconParent.innerHTML = icon;
    icons.appendChild(iconParent);

  });

  dateInfo.innerText = formatDate(new Date());
  dateInfo.className = 'task-date';
  textItem.className = 'list-content';
  textItem.contentEditable = false;
  icons.className = 'action-icons';
  textItem.innerText = task;
  listItem.className = 'list-item';
  // textItem.appendChild(icons);
  listItem.appendChild(textItem);
  // listItem.appendChild(saveEditedTask);
  listItem.appendChild(icons);
  listItem.appendChild(dateInfo);

  return listItem;

}

function addNewTask() {
  var listItem = createNewTask(todoTitle.value);

  todoList.appendChild(listItem);
  todoTitle.value = '';

  var deleteTask = document.querySelectorAll('.delete-task');

  deleteTask.forEach(function(icon) {
    icon.addEventListener("click", function() {
      this.closest("li.list-item").classList.add("hidden");
    });
  });

  var editTask = document.querySelectorAll('.edit-task');

  var icon = listItem.getElementsByClassName("edit-task")[0];

  icon.addEventListener("click", function() {
    var thisParent =
      this.parentElement.parentElement.previousElementSibling;
    switch (thisParent.contentEditable) {
      case "false":
        thisParent.contentEditable = true;
        thisParent.style.backgroundColor = "#efefef";
        this.classList.remove("fas", "fa-edit", "edit-task");
        this.classList.add("fas", "fa-check", "fa-2x");
        break;
      case "true":
        thisParent.contentEditable = false;
        thisParent.style.backgroundColor = "#ffffff";
        this.classList.remove("fas", "fa-check", "fa-2x");
        this.classList.add("fas", "fa-edit", "edit-task");
        break;
    }
  });
};

todoTitle.addEventListener('keyup', function(event) {
  if (event.keyCode === 13 && todoTitle.value.length >= 1) {
    addNewTask();
  }
});
* {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

body {
  font-family: 'Ubuntu', sans-serif;
  font-weight: 400;
  font-size: 100%;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  margin: 0;
  padding: 0;
}

#todoapp {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0px 20px;
}

input.title-input {
  -webkit-transition: all.5s;
  -webkit-transition: all .5s;
  transition: all .5s;
  display: block;
  width: 200px;
  margin: 10px 0;
  padding: 5px 15px;
  border: none;
  border-bottom: 1px solid #ccc;
  outline: none;
  position: relative;
  top: 0;
  left: 50%;
  -webkit-transform: translate(-50%, 0);
  transform: translate(-50%, 0);
  margin-bottom: 50px;
}

input.title-input:focus {
  width: 100%;
  -webkit-box-shadow: 0px 5px 20px 0px rgba(0, 0, 0, 0.75);
  box-shadow: 0px 5px 20px 0px rgba(0, 0, 0, 0.75);
  border-bottom: none;
  border-radius: 15px;
  font-size: 16px;
  padding: 10px 20px;
}

.todo-list {
  list-style-type: none;
  padding: 0;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
  -webkit-box-align: start;
  -ms-flex-align: start;
  align-items: flex-start;
  -webkit-box-pack: start;
  -ms-flex-pack: start;
  justify-content: flex-start;
}

.todo-list .list-item {
  padding: 15px;
  padding-bottom: 5px;
  background-color: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 10px;
  color: #202124;
  margin-bottom: 10px;
  /* min-heiglist-coht: 100px; */
  width: 200px;
  position: relative;
  margin: 5px;
  -webkit-transition: all .25s;
  transition: all .25s;
}

.todo-list .list-item .bg-colors {
  width: 105px;
  height: auto;
  /* height: 100px; */
  background-color: #ffffff;
  position: absolute;
  bottom: 30px;
  left: 0;
  right: 0;
  -webkit-box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.25);
  box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.25);
  /* display: none; */
}

.todo-list .list-item .bg-colors span {
  width: 25px;
  height: 25px;
  /* background-color: #ffffff; */
  display: inline-block;
  margin: 5px;
  border-radius: 50%;
  border: 1px solid #ccc;
}

.todo-list .list-item .bg-colors span:hover {
  border-color: #000000;
}

.todo-list .list-item:hover {
  -webkit-box-shadow: 0px 5px 5px 0px rgba(0, 0, 0, 0.25);
  box-shadow: 0px 5px 5px 0px rgba(0, 0, 0, 0.25);
}

.todo-list .list-item:hover .action-icons {
  opacity: 1;
}

.todo-list .list-item .list-content {
  position: relative;
  min-height: 150px;
  padding: 5px;
}

.todo-list .list-item .task-date {
  font-size: 12px;
  display: block;
  text-align: right;
  padding-top: 10px;
  padding-bottom: 5px;
  border-top: 1px solid #e0e0e0;
}

.todo-list .list-item .action-icons {
  position: relative;
  bottom: 0;
  right: 0;
  left: 0;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: distribute;
  justify-content: space-around;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  margin: 10px 0;
  /* opacity: 0; */
  -webkit-transition: all .25s;
  transition: all .25s;
}

.todo-list .list-item .action-icons .icon-item {
  display: inline-block;
  cursor: pointer;
}

.hidden {
  display: none !important;
}

.visible {
  display: block !important;
}

.fas.fa-check {
  color: green;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384- 
oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">

<div id="todoapp">
  <input type="text" class="title-input" placeholder="Write a note..">
  <ul class="todo-list"></ul>
</div>