我正在尝试将父div内的子项总和相加,但无法将数学范围限制为单亲子级的子项。
我从一个数组开始:
[
{
"item1-name": "item1",
"item1-price": "$100.00",
"item2-name": "item2",
"item2-price": "$200.00",
"item3-name": "item3",
"item3-price": "300.00",
"item4-name": "item4",
"item4-price": "$400.00",
"total": "$1,000.00"
},
{
"item1-name": "item1",
"item1-price": "$100.00",
"item2-name": "item2",
"item2-price": "$200.00",
"item3-name": "item3",
"item3-price": "300.00",
"item4-name": "",
"item4-price": "",
"total": "$0.00"
},
{
"item1-name": "item1",
"item1-price": "$100.00",
"item2-name": "item2",
"item2-price": "$200.00",
"item3-name": "",
"item3-price": "",
"item4-name": "",
"item4-price": "",
"total": "0"
}
]
然后我用javascript将页面内容写成html
function values(row){
return '<div class="container">' +
'<p>' + row["item1-name"] + '<span class="value cost">' +
row["item1-price"] + '</span></p>' +
'<p>' + row["item2-name"] + '<span class="value cost">' +
row["item2-price"] + '</span></p>' +
'<p>' + row["item3-name"] + '<span class="value cost">' +
row["item3-price"] + '</span></p>' +
'<p>' + row["item4-name"] + '<span class="value cost">' +
row["item4-price"] + '</span></p>' +
'<h4>Total' + '<span class="value total">' + row["total"] +
'</span></h4>' +
'</div>';
};
var containers = document.getElementsByClassName("container");
function findTotals(container){
$.each(containers, function(){
var sum = 0;
$(this).children(".cost").each(function() {
var val = $.trim( $(this).text() );
if ( val ) {
val = parseFloat( val.replace( /^\$/, "" ) );
sum += !isNaN( val ) ? val : 0;
}
});
alert(sum);
});
};
function buildRows(rows){
var allRows = "";
rows.forEach(function(row){
allRows = allRows + admitTemplate(row);
})
document.getElementById('rowHolder').innerHTML = allRows;
findTotals();
}
fetch('queryExport.json')
.then(response => {
if (response.ok){
return response.json()
} else {
return Promise.reject('something went wrong!')
}
})
.then(rows => {
buildRows(rows);
})
.catch(error => console.log('error is', error));
问题出在findTotals函数中。我想将总和限制为每个.container div中的.cost值。 (当前总数为1900,当总数为1000、600、300时。)(当我真的想一次遍历一个.container div时,执行页面上的所有.cost值。父(.container)div范围内的功能
您可以看到总计已损坏。我的下一个目标是将总和与总价值进行比较。如果它们不匹配,我将突出显示损坏的总值,因此可以修复生成它的查询。
感谢您的指导。
答案 0 :(得分:0)
您永远不会重置sum
的值,因此循环的每次迭代都会添加到现有值上,而不是独立存在。
答案 1 :(得分:0)
问题出在选择器和DOM构造中:$(this).children。子代查找所有子代的DOM元素,而不是所有子代。 .cost不是.container的子元素,它是p的子元素。如果将其替换为.find,将会得到结果。
function findTotals(container) {
$.each(containers, function() {
var sum = 0;
$(this).find(".cost").each(function() {
var val = $.trim($(this).text());
if (val) {
val = parseFloat(val.replace(/^\$/, ""));
sum += !isNaN(val) ? val : 0;
}
});
console.log(sum);
});
};
这是一个同样有效的小提琴的链接-https://jsfiddle.net/z5oug908/1/
更新后的答案
因此,我对这个问题的思考越深,我越想知道您是否真的需要搜索DOM来求和。您已经在阵列中拥有了所需的所有数据。我们可以使用map,filter和reduce来计算总计,然后再像这样渲染它们:
function calculateTotals(rows) {
return rows.map(row => {
const rowTotal = Object.keys(row).filter(key => {
const match = key.search(/(price)/gi)
return match !== -1;
}).reduce((pre, cur) => {
let val = row[cur];
val = parseFloat(val.replace(/^\$/, ""));
if (val) {
return val + pre;
}
return pre;
}, 0);
row["total"] = rowTotal;
return row;
})
}
应该完成的完整示例:
function calculateTotals(rows) {
return rows.map(row => {
const rowTotal = Object.keys(row).filter(key => {
const match = key.search(/(price)/gi)
return match !== -1;
}).reduce((pre, cur) => {
let val = row[cur];
val = parseFloat(val.replace(/^\$/, ""));
if (val) {
return val + pre;
}
return pre;
}, 0);
row["total"] = rowTotal;
return row;
})
}
function admitTemplate(row) {
return '<div class="container">' +
'<p>' + row["item1-name"] + '<span class="value cost">' +
row["item1-price"] + '</span></p>' +
'<p>' + row["item2-name"] + '<span class="value cost">' +
row["item2-price"] + '</span></p>' +
'<p>' + row["item3-name"] + '<span class="value cost">' +
row["item3-price"] + '</span></p>' +
'<p>' + row["item4-name"] + '<span class="value cost">' +
row["item4-price"] + '</span></p>' +
'<h4>Total' + '<span class="value total">' + row["total"] +
'</span></h4>' +
'</div>';
};
function buildRows(rows) {
var allRows = "";
rows.forEach(function(row) {
allRows = allRows + admitTemplate(row);
})
document.getElementById('rowHolder').innerHTML = allRows;
}
fetch('queryExport.json')
.then(response => {
if (response.ok) {
return response.json()
} else {
return Promise.reject('something went wrong!')
}
})
.then(calculateTotals)
.then(buildRows);