如何使用列表项上的按钮删除列表项

时间:2019-10-01 22:08:52

标签: javascript removechild

我正在建立一个待办事项列表,无法确定删除功能。我不断收到错误消息,指出“找不到节点”。

我自己编写了大部分代码,但是我查找了这部分的教程。他们建议使用:

function removeItem() {
var item = this.parentNode.parentNode;
var parent = this.parentNode;
parent.removeChild(item);
};

我试图将其应用于我已经拥有的代码,但似乎无法正常工作。 我也不清楚以下逻辑:

var item = this.parentNode.parentNode;
var parent = this.parentNode;

如果有人也可以解释这样做的话,将不胜感激。

HTML:

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <link rel="stylesheet" type="text/css" href="resources/css/styles.css">
  </head>
<body>

<header id="addtodo">

  <input type="text" id="input" placeholder="Add an item"/>
  <button id="button"  type="button">Add item</button>
</header>

  <div id="listcontainer">
    <ul id="itemlist">

    </ul>
  </div>

  <div id="dividerline">

  </div>

  <div id="completecontainer">
    <ul id="completed">

    </ul>
  </div>



    <script src="resources/JS/code.js"></script>
  </body>

JavaScript:

document.getElementById('button').addEventListener('click', function(){
var value = document.getElementById('input').value;

var item = document.createElement("li");

var itemText = document.createTextNode(value);

var itemdiv= document.createElement('div');
var buttons=document.createElement('div');
var text=document.createElement('div');

var remove = document.createElement("button");
var complete = document.createElement("button");
var itemlist = document.getElementById('itemlist');




item.appendChild(itemdiv);
itemdiv.appendChild(text);
text.appendChild(itemText);
itemdiv.appendChild(buttons);
buttons.appendChild(complete);
buttons.appendChild(remove);

remove.innerHTML = 'Remove';
complete.innerHTML = 'Complete';

remove.classList.add('remove');
remove.setAttribute('id','remove');

complete.classList.add('complete');
complete.setAttribute('id','complete');

buttons.classList.add('buttondiv');
text.classList.add('text');
itemdiv.classList.add('itemdiv');

remove.addEventListener('click', removeItem);
complete.addEventListener('click', completeItem);

itemlist.insertBefore(item, itemlist.childNodes[0]);
});


function removeItem() {
var item = this.parentNode.parentNode;
var parent = this.parentNode;
parent.removeChild(item);
};

function completeItem() {
var item = this.parentNode.parentNode;
var parent = this.parentNode;
parent.removeChild(item);
};

我希望使用“删除”按钮删除其所附的列表项。

5 个答案:

答案 0 :(得分:2)

错误在于函数

function completeItem() {
  var item = this.parentNode.parentNode;
  var parent = this.parentNode;
  parent.removeChild(item);
};

交换itemparent,就像这样:parent.removeChild(item);

答案 1 :(得分:1)

首先,使用console.log()函数调试代码:

  function removeItem() {
    var item = this.parentNode.parentNode;
    var parent = this.parentNode;
    console.log( 'item', item ); // => <div class="itemdiv">
    console.log( 'parent', parent ); // => <div class="buttondiv">
    parent.removeChild(item);
  };

如您所见:
1)您将项目和父节点混合在一起。
2)如果要删除整个<li>元素,则必须使用更多parentNode

function removeItem() {
  var parent = this.parentNode.parentNode.parentNode.parentNode;
  var item = this.parentNode.parentNode.parentNode;
  console.log( 'item', item ); // => <li>
  console.log( 'parent', parent ); // => <ul id="itemlist">
  parent.removeChild(item);
};

或直接在您的商品上调用remove()方法:

function removeItem() {
  var item = this.parentNode.parentNode.parentNode;
  item.remove();
};

但是最好的方法是使用closest()方法:

function removeItem() {
  var item = this.closest( 'li' );
  item.remove();
};

答案 2 :(得分:1)

在这种情况下,箭头功能是最简单的方法:(以及克隆节点)

const myButton       = document.getElementById('my-button')
    , textInput      = document.getElementById('text-input')
    , ListItems      = document.getElementById('itemlist')
    , LI_clone4Items = document.querySelector('#clone4Items > li')

var count = 0

myButton.onclick=_=>
{
  let newLI = LI_clone4Items.cloneNode(true)
  ListItems.insertBefore(newLI, ListItems.childNodes[0])
  newLI.querySelector('.text').textContent = textInput.value
  newLI.querySelector('.complete').onclick =_=> { ListItems.removeChild(newLI) }
  newLI.querySelector('.remove').onclick   =_=> { ListItems.removeChild(newLI) }
  textInput.value = ''
  myButton.disabled = true
}

(textInputControl =_=> { myButton.disabled = (textInput.value.trim()==='') })()

textInput.oninput = textInputControl
<header id="addtodo">
  <input type="text" id="text-input" placeholder="Add an item" />
  <button id="my-button" type="button">Add item</button>
</header>

<div id="listcontainer">
  <ul id="itemlist"></ul>
</div>

<div id="dividerline">
</div>

<div id="completecontainer">
  <ul id="completed"></ul>
</div>

<!-- hidden -->
<div style="display:none">
  <ul id="clone4Items">
    <li>
      <div class="itemdiv">
        <div class="text"></div>
        <div class="buttondiv">
          <button class="complete" >Complete</button>
          <button class="remove" >Remove</button>
        </div>
      </div>
    </li>
  </ul>

答案 3 :(得分:0)

最简单的解决方案是忘记parentNode,而只给新的<li>一个唯一的类。然后,您可以使用closest()方法删除<li>

此外,您正在创建一些不必要的节点,并且应该更描述性地命名变量。

此外,您不能有多个具有相同id的元素,并且坦率地说,您不需要新元素就将id放在首位,所以就算了。

最后,在继续进行下一个之前,完成所有新元素的创建和配置。它使代码更易于阅读,并防止您忘记进行配置。

var list = document.getElementById("itemlist");
var todo = document.getElementById('input');

document.getElementById('button').addEventListener('click', function(){

  var li = document.createElement("li");
  li.textContent = todo.value;
  li.classList.add("container");

  var itemDiv= document.createElement('div');
  var buttonDiv=document.createElement('div');

  var removeBtn = document.createElement("button");
  removeBtn.textContent = 'Remove';
  removeBtn.addEventListener('click', removeItem);
  removeBtn.classList.add('remove');
  
  var completeBtn = document.createElement("button");
  completeBtn.textContent = 'Complete';
  completeBtn.addEventListener('click', completeItem);
  completeBtn.classList.add('complete');

  // Append your items from the inside out
  buttonDiv.appendChild(completeBtn);
  buttonDiv.appendChild(removeBtn);
  itemDiv.appendChild(buttonDiv);
  li.appendChild(itemDiv);

  list.insertBefore(li, list.childNodes[0]);
});


function removeItem() {
  //Just find the closese ancestor that matches the selector and remove it
  this.closest(".container").remove();
};

function completeItem() {
var item = this.parentNode.parentNode;
var parent = this.parentNode;
parent.removeChild(item);
};
<header id="addtodo">

  <input type="text" id="input" placeholder="Add an item"/>
  <button id="button"  type="button">Add item</button>
</header>

  <div id="listcontainer">
    <ul id="itemlist">

    </ul>
  </div>

  <div id="dividerline">

  </div>

  <div id="completecontainer">
    <ul id="completed">

    </ul>
  </div>

答案 4 :(得分:0)

问题是您如何尝试从父函数中捕获列表项。 this.parentNode.parentNode抓取按钮所在的div项。调用item.parentNode获取外部列表项对象,而不是从父项中删除该项,只需删除整个列表项

document.getElementById('button').addEventListener('click', function(e){
	var value = document.getElementById('input').value;

	var item = document.createElement("li");

  var itemText = document.createTextNode(value);

  var itemdiv= document.createElement('div');
  var buttons=document.createElement('div');
  var text=document.createElement('div');

  var remove = document.createElement("button");
  var complete = document.createElement("button");
  var itemlist = document.getElementById('itemlist');

  item.appendChild(itemdiv);
  itemdiv.appendChild(text);
  text.appendChild(itemText);
  itemdiv.appendChild(buttons);
  buttons.appendChild(complete);
  buttons.appendChild(remove);

  remove.innerHTML = 'Remove';
  complete.innerHTML = 'Complete';

  remove.classList.add('remove');
  remove.setAttribute('id','remove');

  complete.classList.add('complete');
  complete.setAttribute('id','complete');

  buttons.classList.add('buttondiv');
  text.classList.add('text');
  itemdiv.classList.add('itemdiv');

  remove.addEventListener('click', removeItem);
  complete.addEventListener('click', completeItem);

  itemlist.insertBefore(item, itemlist.childNodes[0]);
});


function removeItem() {
  var item = this.parentNode.parentNode;
  var parent = item.parentNode;
  parent.remove()
};

function completeItem() {
  var item = this.parentNode.parentNode;
  var parent = item.parentNode;
  
  parent.remove()
};
<header id="addtodo">

  <input type="text" id="input" placeholder="Add an item"/>
  <button id="button"  type="button">Add item</button>
</header>

  <div id="listcontainer">
    <ul id="itemlist">

    </ul>
  </div>

  <div id="dividerline">

  </div>

  <div id="completecontainer">
    <ul id="completed">

    </ul>
  </div>