这是我对购物单的摆设。https://fiddle.jshell.net/k9L4gamm/ --它快完成了,我最后挣扎的是再次添加删除的项(这是注释的代码)。我的工作是从支付金额减去项目价格,当我改变它的类别时,但是“否则”不想再增加价格。我在编码方面非常初级,我现在正在参加编码入门营,我找不到任何理由说明我的if/can语句不能正常工作。我将非常感谢所有的建议。
发布于 2016-03-05 15:49:12
代码的主要问题在这一行中:
var subRow = myRow[z].lastChild; 它为某些行提供文本节点对象,而不是TD元素。文本节点没有innerHTML属性。由于您的其余代码与此一起工作,所以您在计算中会得到undefined,所以事情就会出错。
但是,由于您已经有了在addProduct函数中计算和的代码,因此在removeBtn事件处理程序中几乎重复该代码是很遗憾的。
因此,我建议创建一个单独的函数,它将计算总数并显示它。这将充分利用您所拥有的两部分代码,从而避免上述问题:
function displayTotal() {
// Code taken from the last part of addProduct:
var toPay = document.getElementsByClassName("altogether");
var suma = 0;
for (var n=0; n<toPay.length;n++) {
// This condition is inspired by the removeBtn click handler:
if (!toPay[n].parentElement.classList.contains("strike")) {
suma = suma + parseFloat(toPay[n].innerHTML);
}
}
// Only put the total at the end, not in the loop:
howMuch.innerHTML = parseFloat(suma);
}虽然与您提到的问题无关,但我也建议您在开始修改表之前进行任何验证检查。检查空输入也是不够的。您还应该检查输入是否为数字。
考虑到这一点,您的addProduct函数可能如下所示:
function addProduct() {
// Before doing anything test the input is complete:
if (quantityInput.value == "" || isNaN(quantityInput.value)) {
alert("Please add quantity");
return; // and exit!
}
if (priceInput.value == "" || isNaN(priceInput.value)) {
alert("Please add price");
return; // and exit!
}
var removeBtn = document.createElement("button");
removeBtn.innerHTML="Skreśl przedmiot";
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
cell5.classList.add("altogether");
cell1.appendChild(removeBtn);
cell2.innerHTML = productInput.value
cell3.innerHTML = parseFloat(quantityInput.value);
cell4.innerHTML = parseFloat(priceInput.value);
cell5.innerHTML = parseFloat(quantity.value)*parseFloat(price.value);
removeBtn.addEventListener("click", function(event){
this.parentElement.parentElement.classList.toggle("strike");
displayTotal();
});
// Code moved to function
displayTotal();
}因此,您注意到在两个位置调用displayTotal :添加产品之后和切换删除之后。这样您就避免了代码重复。
以下是更新的小提琴。
还有什么可以改进的
最好将购物车内容保存在变量中(一个具有项目、价格和数量属性的对象的数组)。这样,您就不必读取HTML元素才能找到这些数据,这不是很有效。
其次,最好将值赋值给textContent,而不是innerHTML。这样你就可以避免特殊字符的问题了。例如,如果您的产品名称中有一个<字符,您将看到它的一部分没有显示。这在textContent中是没有的。
最后,如果在实际应用程序中使用了这一点,那么购物车必须由服务器来管理。这是因为一个网页,和它上的数字可以很容易地修改客户端软件,浏览器外接程序等,所以他们是不可信的。所有检查都必须由服务器应用程序再次完成,服务器应用程序还应该有一个具有正确产品价格的数据库,等等。
发布于 2016-03-05 15:47:28
首先,我可以说(正如@trincot所评论的)-,您确实需要验证这个服务器端!
第二,您的代码是可怕的,缩进严重,不进行输入检查!(例如,我可以输入"foo“作为价格)。
尽管如此,您的问题可以归结为两行代码:
应成为:
for (var z=1;z<myRow.length-1;z++) {(注意,0变成了1,length变成了-1)。
在for循环之后的下一行:
变量subRow = myRowz.lastChild;
需要:
var subRow = myRow[z].children[myRow[z].children.length-1];这是因为(在大多数浏览器中),lastChild将是文本节点,而不是最后一个元素。
发布于 2016-03-05 16:00:55
试试这个解决方案,https://fiddle.jshell.net/uja994ae/。
当您删除一个项目时,您需要再次将一个0放在总数上。然后只增加您需要计数的项目。实际上,并不是一个好的解决方案,只是我在您的代码中调整了解决方案。为了更好地工作,您需要将total (代码中的howMuch.innerHTML)放在全局变量中,并且只增加或减少添加/删除的新项。但是要做到这一点你需要再做一遍所有的代码..。
removeBtn.addEventListener("click", function(event){
var rowToDelete = this.parentElement.parentElement;
var myRow = document.getElementsByTagName("tr");
rowToDelete.classList.toggle("strike");
howMuch.innerHTML = "0";
for (var z=0;z<myRow.length;z++) {
var subRowValue = myRow[z].lastChild.innerHTML;
if (subRowValue && !myRow[z].classList.contains("strike")) {
howMuch.innerHTML = parseFloat(howMuch.innerHTML)+parseFloat(subRowValue);
}
}
});https://stackoverflow.com/questions/35815727
复制相似问题