JavaScript 费用跟踪器计算器 - 减法
JavaScript Expense Tracker Calculator - Subtraction
我正在尝试使用 vanilla javascript 做一个费用跟踪器,用户可以 add/remove 他们的费用项目,费用总额将相应计算。
我正在使用构造函数创建对象,以便稍后我可以保存在 localStorage 中并稍后检索(这部分还没有完成)
问题来了。添加atm没有问题,但是在删除项目时(如果不是按顺序删除),计算就乱了。例如。 Item 1,Item 2,Item 3。如果我用订单移除 Item 3 --> Item2 --> Item 减去总值没有问题。但是如果从Item 1或者Item 2开始移除,计算就会乱
我不确定是不是因为每个项目中都没有 index/id,所以计算不起作用。感谢您的帮助,谢谢!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="ExpenseTracker.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<title>Document</title>
</head>
<body>
<div class="container">
<label name="expense">Expense: </label>
<input id="inputField" name="expense" type="text">
<label name="date">Date: </label>
<input id="start" type="text" name="date">
<label name="amount">Amount: </label>
<input id="money" name="amount" type="number" min="0" step="0.1">
<button id="add" >Add</button>
<table>
<thead>
<tr style="border: 1px solid black;">
<th>Description</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="listContainer" style="border: 1px solid black;">
</tbody>
<tr>
<td id="total">total</td>
</tr>
</table>
<button onclick="clearHistory()">clear localStorage</button>
</div>
<script>
class ExpenseObject{
constructor(e, d, a){
this.expenseDescription = e;
this.dateObject = d;
this.amount = a;
}
}
function clearHistory(){
localStorage.clear();
}
const createDate = flatpickr("#start",{
dateFormat:"d-m-Y ",
});
let addButton = document.getElementById("add");
let listContainer=document.getElementById("listContainer");
let inputField= document.getElementById("inputField");
let dateInput = document.getElementById("start");
let amountField = document.getElementById("money");
let total = document.getElementById("total");
addButton.addEventListener('click', function(){
if(!inputField.value || !dateInput.value || !amountField.value){
alert("please do not leave blank in any field");
return;
}
var newRow = document.createElement('tr');
var expense = document.createElement('td');
var expenseDate = document.createElement('td');
var expenseAmount = document.createElement('td');
var deleteButton = document.createElement('button');
deleteButton.innerHTML="X";
let expenseStuff = new ExpenseObject (inputField.value,dateInput.value,amountField.value )
expense.innerHTML = expenseStuff.expenseDescription;
expenseDate.innerHTML = expenseStuff.dateObject;
expenseAmount.innerText = expenseStuff.amount;
listContainer.appendChild(newRow);
newRow.appendChild(expense);
newRow.appendChild(expenseDate);
newRow.appendChild(expenseAmount);
newRow.appendChild(deleteButton);
inputField.value = "";
amountField.value="";
var totalAmount = parseFloat(total.innerText) || 0;
totalAmount += parseFloat(expenseAmount.innerHTML);
total.innerHTML = totalAmount;
deleteButton.addEventListener('click', function(){
newRow.removeChild(expense);
newRow.removeChild(expenseDate);
newRow.removeChild(expenseAmount);
newRow.removeChild(deleteButton);
totalAmount -= parseFloat(expenseAmount.innerHTML);
total.innerHTML = totalAmount;
})
})
</script>
</body>
</html>
您遇到的主要问题是您在本地范围内声明了 totalAmount
,因此每个 deleteButton
事件监听器仍然引用监听器声明时的旧 totalAmount
值.如果您在更高级别的范围内声明该值,连同 total
,一切都会按预期工作。
这是实际操作:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="ExpenseTracker.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<title>Document</title>
</head>
<body>
<div class="container">
<label name="expense">Expense: </label>
<input id="inputField" name="expense" type="text">
<label name="date">Date: </label>
<input id="start" type="text" name="date">
<label name="amount">Amount: </label>
<input id="money" name="amount" type="number" min="0" step="0.1">
<button id="add" >Add</button>
<table>
<thead>
<tr style="border: 1px solid black;">
<th>Description</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="listContainer" style="border: 1px solid black;">
</tbody>
<tr>
<td id="total">total</td>
</tr>
</table>
<button onclick="clearHistory()">clear localStorage</button>
</div>
<script>
class ExpenseObject{
constructor(e, d, a){
this.expenseDescription = e;
this.dateObject = d;
this.amount = a;
}
}
function clearHistory(){
localStorage.clear();
}
const createDate = flatpickr("#start",{
dateFormat:"d-m-Y ",
});
let addButton = document.getElementById("add");
let listContainer = document.getElementById("listContainer");
let inputField = document.getElementById("inputField");
let dateInput = document.getElementById("start");
let amountField = document.getElementById("money");
let total = document.getElementById("total");
let totalAmount = parseFloat(total.innerText) || 0;
addButton.addEventListener('click', function(){
if(!inputField.value || !dateInput.value || !amountField.value){
alert("please do not leave blank in any field");
return;
}
const newRow = document.createElement('tr');
const expense = document.createElement('td');
const expenseDate = document.createElement('td');
const expenseAmount = document.createElement('td');
const deleteButton = document.createElement('button');
deleteButton.innerHTML="X";
let expenseStuff = new ExpenseObject (inputField.value,dateInput.value,amountField.value )
expense.innerHTML = expenseStuff.expenseDescription;
expenseDate.innerHTML = expenseStuff.dateObject;
expenseAmount.innerText = expenseStuff.amount;
listContainer.appendChild(newRow);
newRow.appendChild(expense);
newRow.appendChild(expenseDate);
newRow.appendChild(expenseAmount);
newRow.appendChild(deleteButton);
inputField.value = "";
amountField.value = "";
totalAmount += parseFloat(expenseAmount.innerHTML);
total.innerHTML = totalAmount;
deleteButton.addEventListener('click', function() {
newRow.removeChild(expense);
newRow.removeChild(expenseDate);
newRow.removeChild(expenseAmount);
newRow.removeChild(deleteButton);
totalAmount -= parseFloat(expenseAmount.innerHTML);
total.innerHTML = totalAmount;
})
})
</script>
</body>
</html>
我正在尝试使用 vanilla javascript 做一个费用跟踪器,用户可以 add/remove 他们的费用项目,费用总额将相应计算。
我正在使用构造函数创建对象,以便稍后我可以保存在 localStorage 中并稍后检索(这部分还没有完成)
问题来了。添加atm没有问题,但是在删除项目时(如果不是按顺序删除),计算就乱了。例如。 Item 1,Item 2,Item 3。如果我用订单移除 Item 3 --> Item2 --> Item 减去总值没有问题。但是如果从Item 1或者Item 2开始移除,计算就会乱
我不确定是不是因为每个项目中都没有 index/id,所以计算不起作用。感谢您的帮助,谢谢!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="ExpenseTracker.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<title>Document</title>
</head>
<body>
<div class="container">
<label name="expense">Expense: </label>
<input id="inputField" name="expense" type="text">
<label name="date">Date: </label>
<input id="start" type="text" name="date">
<label name="amount">Amount: </label>
<input id="money" name="amount" type="number" min="0" step="0.1">
<button id="add" >Add</button>
<table>
<thead>
<tr style="border: 1px solid black;">
<th>Description</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="listContainer" style="border: 1px solid black;">
</tbody>
<tr>
<td id="total">total</td>
</tr>
</table>
<button onclick="clearHistory()">clear localStorage</button>
</div>
<script>
class ExpenseObject{
constructor(e, d, a){
this.expenseDescription = e;
this.dateObject = d;
this.amount = a;
}
}
function clearHistory(){
localStorage.clear();
}
const createDate = flatpickr("#start",{
dateFormat:"d-m-Y ",
});
let addButton = document.getElementById("add");
let listContainer=document.getElementById("listContainer");
let inputField= document.getElementById("inputField");
let dateInput = document.getElementById("start");
let amountField = document.getElementById("money");
let total = document.getElementById("total");
addButton.addEventListener('click', function(){
if(!inputField.value || !dateInput.value || !amountField.value){
alert("please do not leave blank in any field");
return;
}
var newRow = document.createElement('tr');
var expense = document.createElement('td');
var expenseDate = document.createElement('td');
var expenseAmount = document.createElement('td');
var deleteButton = document.createElement('button');
deleteButton.innerHTML="X";
let expenseStuff = new ExpenseObject (inputField.value,dateInput.value,amountField.value )
expense.innerHTML = expenseStuff.expenseDescription;
expenseDate.innerHTML = expenseStuff.dateObject;
expenseAmount.innerText = expenseStuff.amount;
listContainer.appendChild(newRow);
newRow.appendChild(expense);
newRow.appendChild(expenseDate);
newRow.appendChild(expenseAmount);
newRow.appendChild(deleteButton);
inputField.value = "";
amountField.value="";
var totalAmount = parseFloat(total.innerText) || 0;
totalAmount += parseFloat(expenseAmount.innerHTML);
total.innerHTML = totalAmount;
deleteButton.addEventListener('click', function(){
newRow.removeChild(expense);
newRow.removeChild(expenseDate);
newRow.removeChild(expenseAmount);
newRow.removeChild(deleteButton);
totalAmount -= parseFloat(expenseAmount.innerHTML);
total.innerHTML = totalAmount;
})
})
</script>
</body>
</html>
您遇到的主要问题是您在本地范围内声明了 totalAmount
,因此每个 deleteButton
事件监听器仍然引用监听器声明时的旧 totalAmount
值.如果您在更高级别的范围内声明该值,连同 total
,一切都会按预期工作。
这是实际操作:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="ExpenseTracker.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<title>Document</title>
</head>
<body>
<div class="container">
<label name="expense">Expense: </label>
<input id="inputField" name="expense" type="text">
<label name="date">Date: </label>
<input id="start" type="text" name="date">
<label name="amount">Amount: </label>
<input id="money" name="amount" type="number" min="0" step="0.1">
<button id="add" >Add</button>
<table>
<thead>
<tr style="border: 1px solid black;">
<th>Description</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="listContainer" style="border: 1px solid black;">
</tbody>
<tr>
<td id="total">total</td>
</tr>
</table>
<button onclick="clearHistory()">clear localStorage</button>
</div>
<script>
class ExpenseObject{
constructor(e, d, a){
this.expenseDescription = e;
this.dateObject = d;
this.amount = a;
}
}
function clearHistory(){
localStorage.clear();
}
const createDate = flatpickr("#start",{
dateFormat:"d-m-Y ",
});
let addButton = document.getElementById("add");
let listContainer = document.getElementById("listContainer");
let inputField = document.getElementById("inputField");
let dateInput = document.getElementById("start");
let amountField = document.getElementById("money");
let total = document.getElementById("total");
let totalAmount = parseFloat(total.innerText) || 0;
addButton.addEventListener('click', function(){
if(!inputField.value || !dateInput.value || !amountField.value){
alert("please do not leave blank in any field");
return;
}
const newRow = document.createElement('tr');
const expense = document.createElement('td');
const expenseDate = document.createElement('td');
const expenseAmount = document.createElement('td');
const deleteButton = document.createElement('button');
deleteButton.innerHTML="X";
let expenseStuff = new ExpenseObject (inputField.value,dateInput.value,amountField.value )
expense.innerHTML = expenseStuff.expenseDescription;
expenseDate.innerHTML = expenseStuff.dateObject;
expenseAmount.innerText = expenseStuff.amount;
listContainer.appendChild(newRow);
newRow.appendChild(expense);
newRow.appendChild(expenseDate);
newRow.appendChild(expenseAmount);
newRow.appendChild(deleteButton);
inputField.value = "";
amountField.value = "";
totalAmount += parseFloat(expenseAmount.innerHTML);
total.innerHTML = totalAmount;
deleteButton.addEventListener('click', function() {
newRow.removeChild(expense);
newRow.removeChild(expenseDate);
newRow.removeChild(expenseAmount);
newRow.removeChild(deleteButton);
totalAmount -= parseFloat(expenseAmount.innerHTML);
total.innerHTML = totalAmount;
})
})
</script>
</body>
</html>