Как добавить / удалить класс из родительского элемента List (li), когда их дочерний флажок изменен в javascript? - PullRequest
0 голосов
/ 01 июля 2019

Я создаю простое приложение Todo в Javascript, но я застрял, пытаясь добавить / удалить класс для List-item (li), который является родительским для флажка.

По умолчанию флажок списка элементов (Todo) снят (без добавления класса).Всякий раз, когда пользователь устанавливает флажок todo, добавляется класс, и текст todo проходит через строку.

Мне удалось заставить его работать, но ничего не происходит.

// ADD ITEM, REMOVE ITEM - FUNCIONALITY 
const btn = document.getElementById('btn');
const ulList = document.getElementById('list');

// Button event listener with adding li elemnts with input value
btn.addEventListener('click', function() {
  var input = document.getElementById('input').value; // Capture input value
  var newItem = document.createElement("LI"); // Create a <li> node
  newItem.innerHTML = input + '<input type="checkbox" class="checkboxes" ><p class="delet">x</p>'; // Add content to li element for todo.                   
  ulList.insertBefore(newItem, ulList.childNodes[0]); // Insert <li> before the first child of <ul>
  // input = ' ';  // Reset input value to empty field

  // Remove item funcionality 
  newItem.childNodes[2].onclick = function() {
    this.parentNode.remove(this);
  }
})

// ********** IMPORTANT CODE BELOW ***********************
// MARK DONE TODO  - FUNCIONALITY 

var checkBox = document.getElementsByClassName('checkboxes');

for (var i = 0; i < checkBox; i++) {
  checkBox[i].addEventListener('change', function() {
    if (this.checked) {
      // Checkbox is checked..
      this.parentNode.classList.add("line-through");
    } else {
      // Checkbox is not checked..
      this.parentNode.classList.remove("line-through");
    }
  });
}
.line-through {
  text-decoration: line-through;
}
<p class="lead text-center">Welcome to my todoList applications</p>
<div class="row">
  <form id="form" class="col-lg-6 col-8 mx-auto">
    <div class="input-group">
      <input type="text" id="input" class="form-control"><span>
        <button id="btn" type="button" class="btn btn-primary">Submit</button></span>
    </div>
  </form>
</div>
<div class="row">
  <ul id="list" class="list col-lg-6 col-8 mx-auto">
    <!-- <li>this is a todo item <input type="checkbox" class="checkbox"></li>
        <li>this is a todo item <input type="checkbox" class="checkbox"></li> -->
  </ul>
</div>
<div class="row">
  <button id="btnClr" type="button" class="btn btn-primary mx-auto btnHide">Clear All Todos</button>
</div>

Буду признателен за любую помощь.Спасибо всем заранее!:)

Ответы [ 3 ]

2 голосов
/ 01 июля 2019

Полный и рабочий пример ниже. Вообще говоря, проще (для меня, но ваш личный опыт может отличаться) использовать document.createElement вместо .innerHTML для таких задач, как ваша, потому что присоединение слушателей событий к элементам, созданным document.createElement, является (опять же, на мой взгляд, ) намного проще.

В примере создаются новые <li>, <input type="checkbox">, <span> (для заголовка задачи) и <button> (для удаления задачи) при каждом нажатии кнопки «Отправить». После того, как все внутренние элементы созданы, их легко добавить к <li> с помощью .appendChild.

Я пытался использовать описательные имена, поэтому последующие действия не должны быть сложными.

const todoAddBtn = document.getElementById('btn');
const todoDeleteBtn = document.getElementById('btnClr');
const todosList = document.getElementById('list');
const todoInput = document.getElementById('input');

todoAddBtn.addEventListener('click', function(){
  const todoTopic = readAndClearValue(todoInput);
  const todoLi = createListItem();
  const todoCheckbox = createCheckbox();
  const todoTitle = createTitle(todoTopic);
  const todoDelete = createDeleteButton();
  
  todoLi.appendChild(todoCheckbox);
  todoLi.appendChild(todoTitle);
  todoLi.appendChild(todoDelete);
  
  todosList.insertBefore(todoLi, todosList.firstElementChild);
});

todoDeleteBtn.addEventListener('click', function () {
  todosList.innerHTML = '';
});

// readAndClearValue :: HTMLElement -> String
function readAndClearValue (element) {
  const value = element.value;
  element.value = '';
  return value;
}

// createListItem :: () -> HTMLElement
function createListItem () {
  return document.createElement('li');
}

// createTitle :: String -> HTMLElement
function createTitle (text) {
  const title = document.createElement('span');
  title.textContent = text;
  return title;
}

// createDeleteButton :: () -> HTMLElement
function createDeleteButton () {
  const button = document.createElement('button');
  button.textContent = 'X';
  button.className = 'delet';
  button.addEventListener('click', function () {
    button.parentNode.removeChild(button);

    // to remove the <li>, use something like
    // button.parentNode.parentNode.removeChild(button.parentNode)
    // or button.closest('li').remove() if supported
    
  });

  return button;
}

// createCheckbox :: () -> HTMLElement
function createCheckbox () {
  const checkbox = document.createElement('input');
  checkbox.type = 'checkbox';
  checkbox.className = 'checkboxes';
  checkbox.addEventListener('change', function () {
    if (checkbox.checked) {
      checkbox.parentNode.classList.add('line-through');
    } else {
      checkbox.parentNode.classList.remove('line-through');
    }
  });
  
  return checkbox;
}
.line-through {
  text-decoration: line-through;
}
<p class="lead text-center">Welcome to my todoList applications</p>
<div class="row">
  <form id="form" class="col-lg-6 col-8 mx-auto">
    <div class="input-group">
      <input type="text" id="input" class="form-control" >
      <button id="btn" type="button" class="btn btn-primary">Submit</button>
    </div>               
  </form>
</div>            
<div class="row">             
  <ul id="list" class="list col-lg-6 col-8 mx-auto">
  </ul>
</div>
<div class="row">
  <button id="btnClr" type="button" class="btn btn-primary mx-auto btnHide">
    Clear All Todos
  </button>
</div>
0 голосов
/ 01 июля 2019
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <style>
        .line-through li {
            text-decoration: line-through;
        }
    </style>
</head>
<body>
<p class="lead text-center">Welcome to my todoList applications</p>
<div class="row">
    <form id="form" class="col-lg-6 col-8 mx-auto">
        <div class="input-group">
            <input type="text" id="input" class="form-control" ><span>
        <button id="btn" type="button" class="btn btn-primary">Submit</button></span>
        </div>
    </form>
</div>
<div class="row">
    <ul id="list" class="list col-lg-6 col-8 mx-auto">
        <!-- <li>this is a todo item <input type="checkbox" class="checkbox"></li>
              <li>this is a todo item <input type="checkbox" class="checkbox"></li> -->
    </ul>
</div>
<div class="row">
    <button id="btnClr" type="button" class="btn btn-primary mx-auto btnHide">Clear All Todos</button>
</div>
</body>
<script>
    // ADD ITEM, REMOVE ITEM - FUNCIONALITY
    const btn = document.getElementById('btn');
    const ulList = document.getElementById('list');
    let checkBox = document.querySelectorAll('.checkboxes li');


    // Button event listener with adding li elemnts with input value
    btn.addEventListener('click', function(){
        var input = document.getElementById('input').value; // Capture input value
        var newItem = document.createElement("LI");     // Create a <li> node
        newItem.innerHTML = input + '<input type="checkbox" class="checkboxes" ><p class="delet">x</p>';  // Add content to li element for todo.
        ulList.insertBefore(newItem, ulList.childNodes[0]);  // Insert <li> before the first child of <ul>
        // input = ' ';  // Reset input value to empty field

        // Remove item funcionality
        newItem.childNodes[2].onclick = function() {this.parentNode.remove(this);}
    });

    // ********** IMPORTANTO CODE BELOW ***********************
    // MARK DONE TODO  - FUNCIONALITY


    document.body.addEventListener( 'click', function ( event ) {
        if (event.srcElement.className == 'checkboxes') {

                console.log(this);
                this.classList.toggle('line-through');

        }
    });

    checkBox.forEach(el => {
        el.addEventListener('change', myFunction);
    }, false);

    function myFunction(){
        if(this.checked) {
            console.log('here')
            this.classList.toggle('line-through');
        }
    }
</script>
</html>
0 голосов
/ 01 июля 2019

Похоже, вам нужно добавить слушателей после создания флажка.Шат происходит сейчас. Вы загружаете страницу и в начале у вас нет никаких флажков, поэтому, когда вы запускаете цикл, никакие обработчики не подключаются

Вот фрагмент, как заставить его работать.Внесено много изменений, но я постарался оставить подробные комментарии.

Не стесняйтесь спрашивать, если у вас есть какие-либо вопросы:)

https://codesandbox.io/embed/bootstrap-r3ud0

Также здесьявляется частью JS.

const btn = document.getElementById("btn");
const ulList = document.getElementById("list");

// Button event listener with adding li elemnts with input value
btn.addEventListener("click", function() {
  var input = document.getElementById("input").value; // Capture input value
  var newItem = document.createElement("LI"); // Create a <li> node

  // manually create input element
  var inputEl = document.createElement("input");
  // set attributes
  inputEl.type = "checkbox";
  inputEl.class = "checkboxes";

  // also create p element
  var xmark = document.createElement("p");
  xmark.innerHTML = "x";
  xmark.class = "delet";

  // set click handler
  xmark.onclick = function() {
    this.parentNode.remove(this);
  };

  // most important part!
  // we add change listener on input create step
  inputEl.addEventListener("change", changeHandler);
  newItem.innerHTML = input;

  // and append our new elements to the li
  newItem.appendChild(inputEl);
  newItem.appendChild(xmark);

  ulList.insertBefore(newItem, ulList.childNodes[0]); // Insert <li> before the first child of <ul>
});

// create separate handler for change event (first param is event)
const changeHandler = event => {
  // we can access checked property of an element
  const checked = event.target.checked;
  // also we need the target (input in this case) for further manipulations
  const element = event.target;

  if (checked) {
    // Checkbox is checked..
    element.parentNode.classList.add("line-through");
  } else {
    // Checkbox is not checked..
    element.parentNode.classList.remove("line-through");
  }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...