Как удалить элемент списка с помощью кнопки на указанном элементе списка - PullRequest
0 голосов
/ 02 октября 2019

Я создаю список задач, и у меня возникают проблемы с выяснением функции удаления. Я продолжаю получать сообщение об ошибке «Node not found».

Большинство из них я кодировал самостоятельно, но я искал учебник для этой части. Они предложили использовать:

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 ]

2 голосов
/ 02 октября 2019

Ошибка в функции

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

Поменяйте местами item и parent, вот так: parent.removeChild(item);

1 голос
/ 02 октября 2019

Для этого случая функции стрелок являются наиболее простым способом: (и узел клона тоже)

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>
1 голос
/ 02 октября 2019

Сначала используйте функцию 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();
};
0 голосов
/ 02 октября 2019

Проблема в том, как вы пытаетесь захватить элемент списка из родительской функции. 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>
0 голосов
/ 02 октября 2019

Самое простое решение - забыть parentNode и просто дать новому <li> уникальный класс. Затем вы можете удалить <li> с помощью метода closest().

Кроме того, вы создаете несколько ненужных узлов и должны действительно называть переменные более наглядно.

Кроме того, вы не можете иметь несколько элементов с одинаковым id, и, честно говоря, вам не нужны новые элементы, чтобы иметь id s в первую очередь, поэтому забудьте об этом.

Наконец,сделайте все создание и настройку нового элемента, прежде чем переходить к следующему. Это делает код более простым для чтения и позволяет забыть о настройке.

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>
...