待办事项列表关闭按钮

时间:2018-03-13 00:05:02

标签: javascript html web

我有一些似乎有效的代码,但是以一种相当奇怪的方式。当我第一次刷新页面时,我有一个似乎工作正常的关闭按钮,但当我创建一个新的待办事项列表项时,关闭按钮似乎停止工作,我无法确定原因。



let addItem = document.getElementById("submitButton");
let userInput = document.getElementById("toDoInput");
let output = document.getElementById("output");
let toDoItem = document.querySelector(".toDoItem");
let close = document.querySelector(".close");
let toDo = document.querySelector(".todo");

/*User clicked the addItem Button
If there is any text inside the text field then add that text to the todo list */
addItem.addEventListener("click", addToDo);
function addToDo(){
  var html = `
  <ul class="todo">
      <li class="toDoItem">
        <p>${userInput.value}</p>
        <div class="close">X</div>
      </li>
  </ul>
  `;
output.innerHTML += html;
// Resetting input to blank once a submit button has been added.
userInput.value = '';
}


// Figure out how to make closing functionality simple this implementation
// isn't working
close.addEventListener("click", function(e){
  console.log("clicked");
  let x = e.target.parentElement;
  x.style.display = "none";
  e.preventDefault();
});
&#13;
<header>
    <input type="text" placeholder="Enter Item Here..." id="toDoInput">
    <button id="submitButton">+</button>
</header>

<section id="output">
    <ul class="todo">
        <li class="toDoItem">
          <p>Clean Room!</p>
          <div class="close">X</div>
        </li>
    </ul>
</section>
<script src="todo.js"></script>
&#13;
&#13;
&#13;

我也不确定我是否使用过最佳实践,因为我是网络开发的新手,所以任何提示都会受到全面的欢迎!

4 个答案:

答案 0 :(得分:1)

您的关闭按钮需要一个实时事件处理程序。 This example应该有所帮助。为了提供更多功能,如果您能够并且不介意使用JS库,那么使用jQuery会更容易,更直接。

jQuery示例:

$(document).on("click", ".close", function() {
    $(this).parent().hide();
});

无需阻止默认行为,因为它是一个div。

答案 1 :(得分:0)

这里的问题是,当您重新呈现“输出”部分的内容时,会丢失绑定到原始“.close”元素的事件侦听器。解决此问题的一些选项,请参阅this thread以获取一些示例。

答案 2 :(得分:0)

你非常亲密,你绝对不需要jQuery。 如下所示,您无需动态推送<ul>。它永远不会改变!

<header>

    <input type="text" placeholder="Enter Item Here..." id="toDoInput">
    <button id="submitButton">+</button>

</header>

<section id="output">
    <ul class="todo">
    </ul>
</section>

这是你重构的javascript:

let addItem = document.getElementById("submitButton");
let userInput = document.getElementById("toDoInput");
let output = document.getElementById("output");
let toDoItem = document.querySelector(".toDoItem");
let toDo = document.querySelector(".todo");

/*User clicked the addItem Button
If there is any text inside the text field then add that text to the todo 
list */
addItem.addEventListener("click", addToDo);

function addToDo(e){
    e.preventDefault();
    var html = `<li class="toDoItem">
                <p>${userInput.value} </p> <p class="close" 
                onclick="removeChildElement(this);">X</p>
                </li>`;
   output.innerHTML += html;
   let close = document.querySelector(".close")
    // Resetting input to blank once a submit button has been added.
    userInput.value = '';
}


// Figure out how to make closing functionality simple this implementation
// isn't working
function removeChildElement(e) {
    let x = e.parentElement;
    let xParent = x.parentElement;
    xParent.removeChild(x);
    console.log(xParent);
}

你可以看到我做了一些改变。最重要的是你的关闭按钮问题。该函数在其父级(^ 2)上获取父级,然后删除其子级。哪个是你的<li>元素!

享受小提琴:https://jsfiddle.net/fjbyy6uw/35/

答案 3 :(得分:0)

使用Event Delegation。详细信息在演示中进行了评论。添加了<form>,因此可以使用HTMLFormControlsCollection API,它更简单,更少写,而且我很懒。

/* All form controls are referenced by HTMLFormControlsCollection */
var form = document.forms.toDo;
var td = form.elements;
var add = td.add;
var inp = td.input;
var out = td.output;
var toDo = document.querySelector('.toDo');

add.addEventListener("click", addToDo);

/* Limited the dynamically created node to `<li>`. It doesn't make sense to
|| have several `<ul>` having only one `<li>` each.
*/
function addToDo() {
  var html = `
       <li class="item">
        <span>${inp.value}</span>
        <b class="close">X</b>
      </li>
  `;
  toDo.innerHTML += html;

}
/* Event Delegation is a way of leveraging event bubbling so
|| that a single ancestor node can be registered to listen for
|| an event (e.currentTarget) and by means event propagation
|| (bubbling) can locate the event origin (node clicked/e.target).
|| In this demo e.currentTarget is output#output and e.target are
|| any b.close. This was possibble by using e.target in conditions
*/
/* removeChild() is used because display:none is not entirely 
|| gone. The markup remains just not in the DOM, so it may not
|| look like it's there, under certain conditions a node could be
|| considered present.
*/
out.addEventListener("click", function(e) {
  if (e.target !== e.currentTarget) {
    if (e.target.className === "close") {
      let x = e.target.parentElement
      x.parentElement.removeChild(x);
    }
  }
});
.item {
  display: flex;
  max-width: 250px;
  justify-content: space-between;
}

.item span,
.item b {
  display: table-cell;
}

.item b {
  cursor: pointer
}

input,
output,
button {
  font: inherit
}
<form id='toDo'>
  <header>
    <input type="text" placeholder="Enter Item Here..." id="input">
    <button id="add" type='button'>+</button>
  </header>

  <output id="output">
    <ul class="toDo">
        <li class="item">
          <span>Clean Room!</span>
          <b class="close">X</b>
        </li>
    </ul>
</output>

</form>