首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过滤普通javascript待办事项列表中的待办事项

过滤普通javascript待办事项列表中的待办事项
EN

Stack Overflow用户
提问于 2020-09-16 21:28:03
回答 2查看 974关注 0票数 0

我正在构建一个待办事项列表,而现在我一直在尝试实现一个HTML-select下拉列表来过滤已完成和未完成的待办事项。我使用Switch语句来选择要执行的各个块,但是我一直收到以下错误“未捕获TypeError:无法设置未定义的属性'display‘”,但我不知道哪些元素是未定义的。

代码语言:javascript
复制
const input = document.getElementById('input')
const addTodoButton = document.getElementById('addTodoButton')
const todoUL = document.getElementById('todoUL')
const filterOptions = document.querySelector('.filter-todos')

addTodoButton.addEventListener('click', addTodo)
todoUL.addEventListener('click', remove);
filterOptions.addEventListener('click', filterTodos);

// Add todo
function addTodo(e) {
    e.preventDefault()
    const todoText = input.value
    const todoEl = `<li><span>${todoText}</span> <button class="delete" id="deleteTodoButton"><i class="far fa-trash-alt"></i>Delete</button> <button class="complete" id="completeTodoButton"><i class="fas fa-check"></i>Completed</button></li>`
    input.value = ""
    input.focus()

    if (!todoText) {
        alert('You must type a todo')
    } else {
        todoUL.insertAdjacentHTML("beforeend", todoEl)
    }
}

// Remove/Complete todo
function remove(e) {
    if (e.target.id == 'deleteTodoButton') {
        e.target.parentElement.remove()
        input.focus()
    } else {
        e.target.previousElementSibling.previousElementSibling.classList.toggle('completed')
        input.focus()
    }
}

function filterTodos(e) {
    const todos = todoUL.childNodes
    todos.forEach(function (todoEl) {
        switch (e.target.value) {
            case "all":
                todoEl.style.display = "flex"
                break;

            case "completed":
                if (todoEl.classList.contains("completed")) {
                    todoEl.style.display = "flex"
                } else {
                    todoEl.style.display = "none"
                }
                break;
        }
    })
}
代码语言:javascript
复制
ul {
  list-style: none
}

.completed {
  text-decoration: line-through
}
代码语言:javascript
复制
<div class="form-container">
    <h1>Todo List App</h1>
    <form id="form">
      <input type="text" id="input" autocomplete="off" placeholder="Enter your todo">
      <button type="submit" class="add-todo" id="addTodoButton">Add</button>
      <select name="todos" class="filter-todos">
        <option value="all">All</option>
        <option value="completed">Completed</option>
        <option value="uncompleted">Uncompleted</option>
      </select>
    </form>
    <ul id="todoUL">
    </ul>
  </div>

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-16 21:56:28

我已经在我的解释方式中做到了这一点。希望这能在某些方面对你有所帮助。

我已经发现您编写的代码中存在一些问题

首先应该将select的click事件更改为change事件

第二,在使用remove函数的情况下,您必须在将e.target.id == "completeTodoButton"标记为完成之前检查它,否则我们的节点选择将不起作用。

第三,在使用filterTodos函数的情况下,在切换显示之前必须确保节点类型为li。为此,我使用了todoEl.nodeName === "LI"比较。

在切换用例中,您不能使用todoEl.classList.contains("completed"),因为完成的类并不绑定到li,而是绑定到li中的span标记。您可以将这个类移动到li节点并相应地存储元素,或者如果您想继续使用当前结构,则应该使用todoEl.children[0].classList.contains("completed"),因为li的第一个子节点是具有completed类的跨度。

此外,您还遗漏了交换机中的case uncompleted

代码语言:javascript
复制
ul {
    list-style: none;
}

.completed {
    text-decoration: line-through;
}
代码语言:javascript
复制
<div class="form-container">
    <h1>Todo List App</h1>
    <form id="form">
    <input
        type="text"
        id="input"
        autocomplete="off"
        placeholder="Enter your todo"
    />
    <button type="submit" class="add-todo" id="addTodoButton">Add</button>
    <select name="todos" class="filter-todos">
        <option value="all">All</option>
        <option value="completed">Completed</option>
        <option value="uncompleted">Uncompleted</option>
    </select>
    </form>
    <ul id="todoUL"></ul>
</div>

<script>
    const input = document.getElementById("input");
    const addTodoButton = document.getElementById("addTodoButton");
    const todoUL = document.getElementById("todoUL");
    const filterOptions = document.querySelector(".filter-todos");

    addTodoButton.addEventListener("click", addTodo);
    todoUL.addEventListener("click", remove);
    filterOptions.addEventListener("change", filterTodos);

    // Add todo
    function addTodo(e) {
      e.preventDefault();
      const todoText = input.value;
      const todoEl = `<li><span>${todoText}</span>
        <button class="delete" id="deleteTodoButton"><i class="far fa-trash-alt"></i>Delete</button>
        <button class="complete" id="completeTodoButton"><i class="fas fa-check"></i>Completed</button></li>`;
      input.value = "";
      input.focus();

      if (!todoText) {
        alert("You must type a todo");
      } else {
        todoUL.insertAdjacentHTML("beforeend", todoEl);
      }
    }

    // Remove/Complete todo
    function remove(e) {
      if (e.target.id == "deleteTodoButton") {
        e.target.parentElement.remove();
        input.focus();
      } else if (e.target.id == "completeTodoButton") {
        e.target.previousElementSibling.previousElementSibling.classList.toggle(
          "completed"
        );
        input.focus();
      }
    }

    function filterTodos(e) {
      const todos = todoUL.childNodes;
      todos.forEach(function(todoEl) {
        if (todoEl.nodeName === "LI") {
          switch (e.target.value) {
            case "all":
              todoEl.style.display = "flex";
              break;

            case "completed":
              if (todoEl.children[0].classList.contains("completed")) {
                todoEl.style.display = "flex";
              } else {
                todoEl.style.display = "none";
              }
              break;

            case "uncompleted":
              if (todoEl.children[0].classList.contains("completed")) {
                todoEl.style.display = "none";
              } else {
                todoEl.style.display = "flex";
              }
              break;
          }
        }
      });
    }
  </script>

票数 2
EN

Stack Overflow用户

发布于 2020-09-16 21:38:52

代码语言:javascript
复制
const input = document.getElementById('input')
const addTodoButton = document.getElementById('addTodoButton')
const todoUL = document.getElementById('todoUL')
const filterOptions = document.querySelector('.filter-todos')

addTodoButton.addEventListener('click', addTodo)
todoUL.addEventListener('click', remove);
filterOptions.addEventListener('click', filterTodos);

// Add todo
function addTodo(e) {
    e.preventDefault()
    const todoText = input.value
    const todoEl = `<li><span>${todoText}</span> <button class="delete" id="deleteTodoButton"><i class="far fa-trash-alt"></i>Delete</button> <button class="complete" id="completeTodoButton"><i class="fas fa-check"></i>Completed</button></li>`
    input.value = ""
    input.focus()

    if (!todoText) {
        alert('You must type a todo')
    } else {
        todoUL.insertAdjacentHTML("beforeend", todoEl)
    }
}

// Remove/Complete todo
function remove(e) {
    if (e.target.id == 'deleteTodoButton') {
        e.target.parentElement.remove()
        input.focus()
    } else {
        e.target.previousElementSibling.previousElementSibling.classList.toggle('completed')
        input.focus()
    }
}

function filterTodos(e) {
    const todos = todoUL.querySelectorAll('li > span');
    todos.forEach(function (todoEl) {
        const tgt = todoEl.parentElement;
        switch (e.target.value) {
            case "all":
                tgt.style.display = "flex"
                break;

            case "completed":
                if (todoEl.classList.contains("completed")) {
                    tgt.style.display = "flex"
                } else {
                    tgt.style.display = "none"
                }
                break;
            case "uncompleted":
                if (todoEl.classList.contains("completed")) {
                    tgt.style.display = "none"
                } else {
                    tgt.style.display = "flex"
                }
                break;
        }
    })
}
代码语言:javascript
复制
ul {
  list-style: none
}

.completed {
  text-decoration: line-through
}
代码语言:javascript
复制
<div class="form-container">
    <h1>Todo List App</h1>
    <form id="form">
      <input type="text" id="input" autocomplete="off" placeholder="Enter your todo">
      <button type="submit" class="add-todo" id="addTodoButton">Add</button>
      <select name="todos" class="filter-todos">
        <option value="all">All</option>
        <option value="completed">Completed</option>
        <option value="uncompleted">Uncompleted</option>
      </select>
    </form>
    <ul id="todoUL">
    </ul>
  </div>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63921107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档