简体   繁体   English

如何在待办事项列表中添加功能?

[英]how to add functionality in to-do list?

I am working on a to-do list project.我正在做一个待办事项列表项目。 The problem is if someone wants to filter the list by clicking on the buttons active, completed and all applications will not work until you click on the refresh button in the browser before that.问题是,如果有人想通过单击活动、已完成的按钮来过滤列表,并且在此之前单击浏览器中的刷新按钮,所有应用程序都将无法工作。 In this app, I'm also using localStorage.在这个应用程序中,我也在使用 localStorage。 Can someone check the code and tell me why is this happening, please?有人可以检查代码并告诉我为什么会这样吗?

'use strict';

const tabInput = document.querySelector('.tab-input');
const input = document.getElementById('input');
const todosUl = document.querySelector('.todos');
const clearBtn = document.querySelector('.span-right');
const counterItem = document.querySelector('.number');
const body = document.getElementById('body');
const light = document.querySelector('.light');
const icon = document.querySelector('.todo-icon');


// filter 1

const buttons = document.querySelector('.btn-grup');
const filters = document.querySelectorAll('.button--filter');

function btnClicked() {
  buttons.addEventListener('click', (e) => {
    const clicked = e.target;

    if (!clicked) return;

    filters.forEach((filter) => filter.classList.remove('active'));

    clicked.classList.add('active');
  });
}

// filter

let todosEl = document.querySelectorAll('li');
// completed
function filterCompleted() {
  todosEl.forEach((el) => {
    if (!el.classList.contains('completed')) {
      el.style.display = 'none';
    } else {
      el.style.display = 'block';
    }
  });
}

// active
function filterActive() {
  todosEl.forEach((el) => {
    if (el.classList.contains('completed')) {
      el.style.display = 'none';
    } else {
      el.style.display = 'block';
    }
  });
}
// all
function filterAll() {
  let todosEl = document.querySelectorAll('li');
  todosEl.forEach((el) => {
    if (el || el.classList.contains('completed')) {
      el.style.display = 'block';
    }
  });
}
// btn clear
clearBtn.addEventListener('click', (e) => {
  localStorage.clear();
  location.reload();
});

HTML HTML

<form class="tab-input" id="tab-input">
          <input
            type="text"
            class="input"
            id="input"
            placeholder="Create a new todo..."
            autocomplete="off"
          />
          <ul class="todos" id="todos"></ul>
          <div class="item-info">
            <span class="span-left"
              ><span class="number"></span> items left</span
            >
            <span class="span-right">Clear</span>
          </div>
          <div class="btn-grup">
            <button
              class="button--filter active"
              onclick="filterAll(); btnClicked()"
              id="filter-all"
              type="button"
            >
              All
            </button>
            <button
              class="button--filter"
              onclick="filterActive(); btnClicked()"
              id="filter-active"
              type="button"
            >
              Active
            </button>
            <button
              class="button--filter"
              onclick="filterCompleted(); btnClicked()"
              id="filter-completed"
              type="button"
            >
              Completed
            </button>
          </div>
        </form>

The problem is with your todosEl object.问题出在您的todosEl object 上。 You initialize it at the start of the program as a global variable and it's never updated again, so your filterActive and filterCompleted functions work from that empty list forever more.您在程序开始时将其初始化为全局变量,并且它永远不会再次更新,因此您的filterActivefilterCompleted函数将永远在该空列表中工作。 The filterAll function declares the variable again in its own scope, which is what all of the filter functions should do. filterAll function 在自己的 scope 中再次声明了变量,这是所有过滤器函数都应该做的。 Since the list items get changed as you use the program (adding or setting complete/active) you must get the list each time you're filtering.由于列表项在您使用程序时会发生变化(添加或设置完成/活动),因此每次过滤时都必须获取列表。 Change your filter functions like this and it should work:像这样更改您的过滤器功能,它应该可以工作:

// let todosEl = document.querySelectorAll('li'); <--- delete this global var
// completed
function filterCompleted() {
  const todosEl = document.querySelectorAll('li');  <--- get it fresh each time
  todosEl.forEach((el) => {
    if (!el.classList.contains('completed')) {
      el.style.display = 'none';
    } else {
      el.style.display = 'block';
    }
  });
}
// active
function filterActive() {
  const todosEl = document.querySelectorAll('li');  <--- get it fresh each time
  todosEl.forEach((el) => {
    if (el.classList.contains('completed')) {
      el.style.display = 'none';
    } else {
      el.style.display = 'block';
    }
  });
}
// all
function filterAll() {
  const todosEl = document.querySelectorAll('li');  <--- get it fresh each time
  todosEl.forEach((el) => {
    if (el || el.classList.contains('completed')) {
      el.style.display = 'block';
    }
  });
}

I also declared todoesEl as const since it doesn't need to change.我还将todoesEl声明为const ,因为它不需要更改。

HTML HTML

 <button
         class="button--filter active"
         onclick="filterAll(); btnClicked()"
         id="filter-all"
         type="button"
>

Javascript Javascript

function btnClicked() {
  buttons.addEventListener('click', (e) => {
    const clicked = e.target;

    if (!clicked) return;

    filters.forEach((filter) => filter.classList.remove('active'));

    clicked.classList.add('active');
  });
}

This above looks weird.上面这个看起来很奇怪。 Every time you click on a button, you create a eventlistener on buttons (a collection of nodes).每次单击按钮时,都会在buttons (节点集合)上创建一个事件监听器。 Try onclick="btnClicked(this)" on the button and rewrite the method to the following:在按钮上尝试onclick="btnClicked(this)"并将方法重写为以下内容:

function btnClicked(clicked) {
    filters.forEach((filter) => filter.classList.remove('active'));

    clicked.classList.add('active');
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM