计算 lis 的数量并保存到 html 元素

Count number of lis and save to an html element

我正在制作一个待办事项页面,想统计待办事项的数量并显示它们。

<div class='numtodos'>3</div>

我想在numtodos.

的文本内容中显示在这里

尝试使用 jQuery 计算待办事项的数量(我也可以使用非 jQuery 答案)。

我知道我需要 <li> 个元素的长度,但是我应该如何保存它以便在添加新待办事项时更新。

这是我的密码笔。试图使右边的大数字成为待办事项的数量。

$('ul').on('click', 'li', function() {
  $(this).toggleClass('completed');
})


$('ul').on('click', 'span', function(event) {
  $(this).parent().fadeOut(500, function() {
    $(this).remove();
  })
  event.stopPropagation();
});

$("input[type='text']").keypress(function(event) {
  if (event.which === 13) {
    //get the new todo text from inut
    var todoText = $(this).val();
    $(this).val('');
    //create a new li and add it ul
    $('ul').append('<li><i class="far fa-circle"></i> ' + todoText + ' <span>X</span></li>')

  }
});

$(".fa-plus-circle").click(function() {
  $("input[type='text']").fadeToggle();
});

// let lis = document.querySelectorAll('li');
// let input = document.querySelector('input');
// let numtodos = document.querySelector('.numtodos')

// input.addEventListener('change', function(){
//     let howmany = lis.length;
//     numtodos.textContent= howmany;

// })

$('input').change(function() {
  console.log($('.numtodos'));
})
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: rgb(67, 0, 192);
  font-family: 'Roboto', sans-serif;
}

.container {
  background-color: whitesmoke;
  width: 480px;
  height: 100%;
  padding: 35px 40px;
}


/* NAV */

#nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.tinyburger {
  cursor: pointer;
}

.line {
  height: 3px;
  width: 21px;
  background: black;
  margin: 3px;
  border-radius: 1px;
}


/* header */

.header {
  display: flex;
  margin: 40px 0px 30px;
  font-family: 'Roboto Condensed', sans-serif;
}

h1 {
  margin-right: 8px;
  font-size: 3em;
}

h2 {
  font-size: 1.4em;
  margin-top: 26px;
  color: rgb(153, 153, 153);
}


/* Input */

input {
  width: 100%;
  padding: 10px 5px;
  border: none;
  font-size: 17px;
}

ul {
  list-style: none;
}

li {
  line-height: 1.2;
  border-bottom: 1px rgb(202, 202, 202) solid;
  margin: 20px 5px;
  padding: 0px 0 20px 0;
  font-weight: bold;
  cursor: pointer;
}

li span {
  float: right;
}

.fa-plus-circle {
  color: rgb(67, 0, 192);
  font-size: 40px;
  text-align: center;
  width: 100%;
  margin-top: 30px;
}

.numtodos {
  font-size: 12em;
  position: absolute;
  top: 0%;
  left: 75%;
  line-height: 0.7;
  color: rgba(153, 153, 153, 0.2);
  font-family: 'Roboto Condensed', sans-serif;
}

.fa-circle {
  color: rgba(153, 153, 153, 0.4);
  font-size: 20px;
}

.completed {
  text-decoration: line-through;
  color: grey;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />

<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:ital,wght@0,400;1,700&family=Roboto:wght@400;500;700;900&display=swap" rel="stylesheet">
</head>

<body>

  <div class="container">
    <div id='nav'>
      <div class='tinyburger'>
        <div class='line'></div>
        <div class='line'></div>
        <div class='line'></div>
      </div>
      <i class="fas fa-search"></i>
    </div>
    <div class="header">
      <h1>TO-DO</h1>
      <h2 class="date">NOV 23</h2>
    </div>
    <input type="text" name='newtodo' id='newtodo' placeholder="Write a new to-do">
    <ul class='todos'>
      <li><i class="far fa-circle"></i> Lunch with Helena Barnes <span>X</span> </li>
      <li><i class="far fa-circle"></i> Evening Workout<span>X</span></li>
      <li><i class="far fa-circle"></i> Lunch with Helena Barnes <span>X</span></li>
    </ul>
    <i class="fas fa-plus-circle"></i>
    <div class='numtodos'>3</div>
  </div>

  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

https://codepen.io/laurynatlanta/pen/QWNxYeN

我觉得这样应该没问题:

// Get todos number container div element.
var numTodosContainer = document.getElementsByClassName('numtodos')[0];

// Get all todos available.
var todos = document.getElementsByClassName(todosclassname);

// Get todos length to add it to the container.
var lastTodosNum = todos.length;

// Add it to the container.
numTodosContainer.innerHTML = lastTodosNum;

// Loop to check every 10ms if the number of todos is changed.
setInterval(function(){

     // This variable will change every 10ms to get the new todos number.
     var newTodosNum = document.getElementsByClassName(todosclassname).length;

     // Check if the new number isn't equals the old num.
     if (newTodosNum != lastTodosNum) {

           numTodosContainer.innerHTML = newTodosNum;

     }

     // Make lastTodosNum equals newTodosNum to stop the if statement above from execute the code block inside it.
     lastTodosNum = newTodosNum;

}, 10);

你必须这样做:

const numtodos = document.querySelector('div.numtodos')

numtodos.setCount =_=> { 
  numtodos.textContent = document.querySelectorAll('ul.todos>li:not(.completed)').length
}

然后在正确的地方添加numtodos.setCount();

所以,你的 JS 变成了:

const numtodos = document.querySelector('div.numtodos')

numtodos.setCount =_=> { 
  numtodos.textContent = document.querySelectorAll('ul.todos>li:not(.completed)').length
}

$('ul').on('click', 'li', function () {
  $(this).toggleClass('completed');
  numtodos.setCount();
});

$('ul').on('click', 'span', function (event) {
  $(this).parent().fadeOut(500, function () {
    $(this).remove();
    numtodos.setCount();
  });
  event.stopPropagation();
});

$("input[type='text']").keypress(function (event) {
  if (event.which === 13) {
    //get the new todo text from inut
    var todoText = $(this).val();
    $(this).val('');
    //create a new li and add it ul
    $('ul').append(`<li><i class="far fa-circle"></i>${todoText}<span>X</span></li>`);
    numtodos.setCount();
  }
});

$(".fa-plus-circle").click(function () {
  $("input[type='text']").fadeToggle();
});

根据您当前的代码,我建议创建以下命名函数,然后在您要更新 to-do 列表的代码区域调用该函数(无论是添加到,或从中删除):

// we're not planning to change the function within the code, so we
// declare using 'const' (though 'let' would be perfectly okay, but would
// potentially allow for the variable to be overwritten); we also use
// Arrow function syntax since - within the function - we have no need
// to use 'this':
const todosLength = () => {

  // here we find the number of <li> elements that do not have
  // the class of 'completed' that are the children of a parent
  // with the class of 'todos'; and then we retrieve the length
  // of the resulting jQuery collection:
  const num = $('.todos > li:not(.completed)').length;

  // here we set the text of the element(s) with the
  // class of 'numtodos':
  $('.numtodos').text(num);

  // here we return the number to the calling context
  // (just in case it's ever of use):
  return num;
};

将以上内容与您的代码合并后,会产生以下内容:

const todosLength = () => {
  const num = $('.todos li:not(.completed)').length;
  $('.numtodos').text(num);
  return num;
}

$('ul').on('click', 'li', function() {
  $(this).toggleClass('completed');
})


$('ul').on('click', 'span', function(event) {
  $(this).parent().fadeOut(500, function() {
    $(this).remove();
    todosLength();
  });
  event.stopPropagation();
});

$("input[type='text']").keypress(function(event) {
  if (event.which === 13) {
    //get the new todo text from inut
    var todoText = $(this).val();
    $(this).val('');
    //create a new li and add it ul
    $('ul').append('<li><i class="far fa-circle"></i> ' + todoText + ' <span>X</span></li>');
    todosLength();

  }
});

$(".fa-plus-circle").click(function() {
  $("input[type='text']").fadeToggle();
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: rgb(67, 0, 192);
  font-family: 'Roboto', sans-serif;
}

.container {
  background-color: whitesmoke;
  width: 480px;
  height: 100%;
  padding: 35px 40px;
}


/* NAV */

#nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.tinyburger {
  cursor: pointer;
}

.line {
  height: 3px;
  width: 21px;
  background: black;
  margin: 3px;
  border-radius: 1px;
}


/* header */

.header {
  display: flex;
  margin: 40px 0px 30px;
  font-family: 'Roboto Condensed', sans-serif;
}

h1 {
  margin-right: 8px;
  font-size: 3em;
}

h2 {
  font-size: 1.4em;
  margin-top: 26px;
  color: rgb(153, 153, 153);
}


/* Input */

input {
  width: 100%;
  padding: 10px 5px;
  border: none;
  font-size: 17px;
}

ul {
  list-style: none;
}

li {
  line-height: 1.2;
  border-bottom: 1px rgb(202, 202, 202) solid;
  margin: 20px 5px;
  padding: 0px 0 20px 0;
  font-weight: bold;
  cursor: pointer;
}

li span {
  float: right;
}

.fa-plus-circle {
  color: rgb(67, 0, 192);
  font-size: 40px;
  text-align: center;
  width: 100%;
  margin-top: 30px;
}

.numtodos {
  font-size: 12em;
  position: absolute;
  top: 0%;
  left: 75%;
  line-height: 0.7;
  color: rgba(153, 153, 153, 0.2);
  font-family: 'Roboto Condensed', sans-serif;
}

.fa-circle {
  color: rgba(153, 153, 153, 0.4);
  font-size: 20px;
}

.completed {
  text-decoration: line-through;
  color: grey;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:ital,wght@0,400;1,700&family=Roboto:wght@400;500;700;900&display=swap" rel="stylesheet">
<div class="container">
  <div id='nav'>
    <div class='tinyburger'>
      <div class='line'></div>
      <div class='line'></div>
      <div class='line'></div>
    </div>
    <i class="fas fa-search"></i>
  </div>
  <div class="header">
    <h1>TO-DO</h1>
    <h2 class="date">NOV 23</h2>
  </div>
  <input type="text" name='newtodo' id='newtodo' placeholder="Write a new to-do">
  <ul class='todos'>
    <li><i class="far fa-circle"></i> Lunch with Helena Barnes <span>X</span> </li>
    <li><i class="far fa-circle"></i> Evening Workout<span>X</span></li>
    <li><i class="far fa-circle"></i> Lunch with Helena Barnes <span>X</span></li>
  </ul>
  <i class="fas fa-plus-circle"></i>
  <div class='numtodos'>3</div>
</div>

<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

JS Fiddle demo.

参考文献: