JavaScript中HTML表内容列和行的平均值
所以我遇到了这个问题,我需要每列和每行的平均值,如下所示:JavaScript中HTML表内容列和行的平均值,javascript,html,Javascript,Html,所以我遇到了这个问题,我需要每列和每行的平均值,如下所示: 7 9 8 5 7 9 6 6 8 // assigning the result of the immediately-invoked function expression // (IIFE), the format of - among others - (function(){})() // the final parentheses allow us to pass an argument to the enclosed /
7 9 8
5 7 9
6 6 8
// assigning the result of the immediately-invoked function expression
// (IIFE), the format of - among others - (function(){})()
// the final parentheses allow us to pass an argument to the enclosed
// function, to the 'averageTables' variable for subsequent use if
// required:
let averageTables = (function(opts) {
/* the 'opts' Object passed as the argument is as follows:
{
// String: the CSS selector to identify the relevant
// <table> elements:
'table': '#myTable, #myOtherStrangelyIdenticalTable',
// Boolean: whether or not you want to see the last cell
// in the <table> the average of the averages column
'hideAverageOfAverages': false,
// String: the class-name to add to the <td> containing
// the average of each <tr>:
'rowAverageClassName': 'rowAverage',
// String: the class-name to add to the <td> containing
// the average of each column:
'columnAverageClassName': 'columnAverage',
// String: the class-name to add to the <td> containing
// the average of the column of averages:
'averageOfAveragesClassName': 'averageOfAverage',
// Number: the number of decimal places to which the
// averages should be rounded:
'decimalPlaces': 1
}
*/
// here we use document.querySelectorAll() to retrieve the relevant
// <table> elements, assuming that the opts.table selector results
// in a selection of <table> elements:
let tableElements = document.querySelectorAll(opts.table),
// we use Array.from() to convert the NodeList from
// document.querySelectorAll() into an Array:
allTables = Array.from(tableElements),
// here we create a new <td> element:
newCell = document.createElement('td'),
// here we find the divisor, and multiplier, for
// accurately (insofar as JavaScript can) round
// to a set number of decimal places:
nDecimals = Math.pow(10, opts.decimalPlaces),
// and initialise some empty variables for later
// use:
rows, column, cell, average;
// here we use the Element.classList interface to add
// the class-name passed in from the opts Object:
newCell.classList.add(opts.rowAverageClassName);
// we iterate over the Array of <table> elements using
// Array.prototype.forEach():
allTables.forEach(function(table) {
// 'table' is a reference to the current <table> of the
// Array of <table> elements over which we're iterating.
// we cache the <tr> elements, as an Array, recovered
// from the HTMLTableElement.rows collection:
rows = Array.from(table.rows);
// iterating over that Array of <tr> elements:
rows.forEach(function(row) {
// 'row' is a reference to the current <tr> element
// from the Array of <tr> elements over which we're
// iterating.
// here we use Array.from() to create an Array of the
// <td> elements that are the element-children of the
// current <tr> element:
average = Array.from(row.children)
// we then use Array.prototype.reduce() to reduce
// that Array to a single element:
.reduce(function(value, currentCell) {
// 'value': the current value of the reduce method,
// (initialised to 0 as the final argument following
// the anonymous function),
// currentCell: the current <td> element of the
// Array of <td> elements over which we're iterating.
// here we add the currently-held value to the result
// of retrieving the text-content of the current <td>,
// and using String.prototype.trim() to remove any
// leading or trailing white-space, and then passing
// that resultant String to parseFloat() to convert
// a numeric String to a number (if possible); note
// that there are no sanity checks, so if the text
// cannot be converted to a Number then the result of
// reduce() will be either undefined or NaN.
// This approach, obviously finds the sum of the text
// of all <td> elements:
return value + parseFloat(currentCell.textContent.trim());
// following the summation, then, we divide it by the number
// of <td> elements within the <tr> to find the average:
}, 0) / row.children.length;
// we clone the created <td> element:
cell = newCell.cloneNode();
// and set its text-content to the result of the following,
// in which we multiply the found average by the value of
// nDecimals, and use Math.round() on the result, and then
// divide by the result of nDecimals to find the result to
// the user-defined number of decimal places (using
// Number.toFixed(n) will simply cut off the number without
// rounding, which is possibly not a big issue in your use-case):
cell.textContent = Math.round(average * nDecimals ) / nDecimals ;
// here we append the created, cloned <td> to the current <tr>:
row.appendChild(cell);
});
// here we simply find the last <tr> element in the <table>,
// and then clone that node, including its children, using
// cloneNode(true); it's worth remembering that
// document.querySelector() returns only a single node, if any,
// which is the first element it finds that matches the supplied
// CSS selector:
let newRow = table.querySelector('tr:last-child').cloneNode(true);
// here we use Array.from() to convert the NodeList of newRow.children
// into an Array, and then use Array.prototype.forEach() to iterate
// over that Array:
Array.from(newRow.children).forEach(function(cell, index) {
// 'cell': a reference to the current <td> element of the
// Array of <td> elements over which we're iterating,
// 'index': the index of the current <td> within the Array
// over which we're iterating.
// retrieving a collection of <td> elements using the CSS
// td:nth-child(), and interpolating the result of 'index + 1'
// as the argument to :nth-child(); we add 1 to the index
// because JavaScript is zero-based, whereas CSS is one-based; and
// then using Array.from() to convert that collection into
// an Array:
column = Array.from(table.querySelectorAll('td:nth-child(' + (index + 1) + ')'));
// here we calculate the average exactly the same way as above,
// but over the columns rather than the rows:
average = column.reduce(function(value, currentCell) {
return value + parseFloat(currentCell.textContent.trim());
}, 0) / column.length;
// we set the cell's text-content exactly the same way
// as above (which in DRY terms is, admittedly, ridiculous):
cell.textContent = Math.round(average * 10) / 10;
// here we add the user-supplied class-name to the
// column-average <td> elements:
cell.classList.add(opts.columnAverageClassName);
});
// and we then append the newRow to the current <table>
// element:
table.appendChild(newRow);
// here we find the :last-child of the newly-added row,
// which is the <td> containing the average of the
// averages column:
let averageOfAverage = newRow.querySelector('td:last-child');
// here we set the display of that <td>, if the user wants to
// hide the cell (opts.hideAverageOfAverages is true) then
// we set the display style to 'none'; otherwise (if
// opts.hideAverageOfAverages is anything other than exactly true)
// we set the display to that of 'table-cell':
averageOfAverage.style.display = opts.hideAverageOfAverages === true ? 'none' : 'table-cell';
// and then we add the requisite, user-defined, class-name:
averageOfAverage.classList.add(opts.averageOfAveragesClassName);
});
// at this point we return the Array of <tables> found
// to the calling context if the user wants to have
// use to them for any other reason:
return allTables;
})({
'table': '#myTable, #myOtherStrangelyIdenticalTable',
'hideAverageOfAverages': false,
'rowAverageClassName': 'rowAverage',
'columnAverageClassName': 'columnAverage',
'averageOfAveragesClassName': 'averageOfAverage',
'decimalPlaces': 1
});
致:
这就是我到目前为止所做的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table id="myTable">
<tr>
<td>7</td>
<td>9</td>
<td>8</td>
</tr>
<tr>
<td>5</td>
<td>7</td>
<td>9</td>
</tr>
<tr>
<td>6</td>
<td>6</td>
<td>8</td>
</tr>
</table>
<script src="script.js"></script>
</body>
</html>
我是JavaScript新手。有没有更好的方法来实现这种效果?您可以使用嵌套的
进行循环。创建一个填充有0
的数组,在设置行的平均值之后,为中的每个索引设置循环、求和和和平均垂直列的值。注意,要包括最后一行单元格处平均值的平均值,请将len
调整为len=cols.length
,即在len=cols.length-1
处删除-1
,最后用于循环
(函数(){
var table=document.getElementById(“myTable”);
var行=table.rows;
//存储列和
var cols=Array.from({length:row.length+1},()=>0);
对于(var i=0;row.length>i;i++){
var td=document.createElement('td');
var总和=0;
对于(var j=n=0;j
7.
9
8.
5.
7.
9
6.
6.
8.
这将使您走上正确的道路
此代码用于水平计算平均值。这是一个如何使用for
循环遍历HTML
元素的示例,以字符串形式获取它们的内容,并将它们转换为ints
var table=document.getElementById("myTable");
var rows=table.rows;
for(var i = 0; i < rows.length; i++){
var cells = rows[i].cells;
var sum = 0;
for(var x = 0; x < cells.length; x++){
var cell = cells[x];
sum += parseInt(cell.innerHTML);
}
var average = sum/cells.length;
rows[i].innerHTML += "<td>"+average+"</td>";
}
var table=document.getElementById(“myTable”);
var rows=table.rows;
对于(变量i=0;i
您可以使用parseFloat((sum/3).toFixed(1))
对总和进行四舍五入:
var table=document.getElementById(“myTable”);
var rows=table.rows;
var myTable2=document.getElementById(“myTable2”);
var newRows='';
for(设i=0;i
7.
9
8.
5.
7.
9
6.
6.
8.
一种方法如下:
7 9 8
5 7 9
6 6 8
// assigning the result of the immediately-invoked function expression
// (IIFE), the format of - among others - (function(){})()
// the final parentheses allow us to pass an argument to the enclosed
// function, to the 'averageTables' variable for subsequent use if
// required:
let averageTables = (function(opts) {
/* the 'opts' Object passed as the argument is as follows:
{
// String: the CSS selector to identify the relevant
// <table> elements:
'table': '#myTable, #myOtherStrangelyIdenticalTable',
// Boolean: whether or not you want to see the last cell
// in the <table> the average of the averages column
'hideAverageOfAverages': false,
// String: the class-name to add to the <td> containing
// the average of each <tr>:
'rowAverageClassName': 'rowAverage',
// String: the class-name to add to the <td> containing
// the average of each column:
'columnAverageClassName': 'columnAverage',
// String: the class-name to add to the <td> containing
// the average of the column of averages:
'averageOfAveragesClassName': 'averageOfAverage',
// Number: the number of decimal places to which the
// averages should be rounded:
'decimalPlaces': 1
}
*/
// here we use document.querySelectorAll() to retrieve the relevant
// <table> elements, assuming that the opts.table selector results
// in a selection of <table> elements:
let tableElements = document.querySelectorAll(opts.table),
// we use Array.from() to convert the NodeList from
// document.querySelectorAll() into an Array:
allTables = Array.from(tableElements),
// here we create a new <td> element:
newCell = document.createElement('td'),
// here we find the divisor, and multiplier, for
// accurately (insofar as JavaScript can) round
// to a set number of decimal places:
nDecimals = Math.pow(10, opts.decimalPlaces),
// and initialise some empty variables for later
// use:
rows, column, cell, average;
// here we use the Element.classList interface to add
// the class-name passed in from the opts Object:
newCell.classList.add(opts.rowAverageClassName);
// we iterate over the Array of <table> elements using
// Array.prototype.forEach():
allTables.forEach(function(table) {
// 'table' is a reference to the current <table> of the
// Array of <table> elements over which we're iterating.
// we cache the <tr> elements, as an Array, recovered
// from the HTMLTableElement.rows collection:
rows = Array.from(table.rows);
// iterating over that Array of <tr> elements:
rows.forEach(function(row) {
// 'row' is a reference to the current <tr> element
// from the Array of <tr> elements over which we're
// iterating.
// here we use Array.from() to create an Array of the
// <td> elements that are the element-children of the
// current <tr> element:
average = Array.from(row.children)
// we then use Array.prototype.reduce() to reduce
// that Array to a single element:
.reduce(function(value, currentCell) {
// 'value': the current value of the reduce method,
// (initialised to 0 as the final argument following
// the anonymous function),
// currentCell: the current <td> element of the
// Array of <td> elements over which we're iterating.
// here we add the currently-held value to the result
// of retrieving the text-content of the current <td>,
// and using String.prototype.trim() to remove any
// leading or trailing white-space, and then passing
// that resultant String to parseFloat() to convert
// a numeric String to a number (if possible); note
// that there are no sanity checks, so if the text
// cannot be converted to a Number then the result of
// reduce() will be either undefined or NaN.
// This approach, obviously finds the sum of the text
// of all <td> elements:
return value + parseFloat(currentCell.textContent.trim());
// following the summation, then, we divide it by the number
// of <td> elements within the <tr> to find the average:
}, 0) / row.children.length;
// we clone the created <td> element:
cell = newCell.cloneNode();
// and set its text-content to the result of the following,
// in which we multiply the found average by the value of
// nDecimals, and use Math.round() on the result, and then
// divide by the result of nDecimals to find the result to
// the user-defined number of decimal places (using
// Number.toFixed(n) will simply cut off the number without
// rounding, which is possibly not a big issue in your use-case):
cell.textContent = Math.round(average * nDecimals ) / nDecimals ;
// here we append the created, cloned <td> to the current <tr>:
row.appendChild(cell);
});
// here we simply find the last <tr> element in the <table>,
// and then clone that node, including its children, using
// cloneNode(true); it's worth remembering that
// document.querySelector() returns only a single node, if any,
// which is the first element it finds that matches the supplied
// CSS selector:
let newRow = table.querySelector('tr:last-child').cloneNode(true);
// here we use Array.from() to convert the NodeList of newRow.children
// into an Array, and then use Array.prototype.forEach() to iterate
// over that Array:
Array.from(newRow.children).forEach(function(cell, index) {
// 'cell': a reference to the current <td> element of the
// Array of <td> elements over which we're iterating,
// 'index': the index of the current <td> within the Array
// over which we're iterating.
// retrieving a collection of <td> elements using the CSS
// td:nth-child(), and interpolating the result of 'index + 1'
// as the argument to :nth-child(); we add 1 to the index
// because JavaScript is zero-based, whereas CSS is one-based; and
// then using Array.from() to convert that collection into
// an Array:
column = Array.from(table.querySelectorAll('td:nth-child(' + (index + 1) + ')'));
// here we calculate the average exactly the same way as above,
// but over the columns rather than the rows:
average = column.reduce(function(value, currentCell) {
return value + parseFloat(currentCell.textContent.trim());
}, 0) / column.length;
// we set the cell's text-content exactly the same way
// as above (which in DRY terms is, admittedly, ridiculous):
cell.textContent = Math.round(average * 10) / 10;
// here we add the user-supplied class-name to the
// column-average <td> elements:
cell.classList.add(opts.columnAverageClassName);
});
// and we then append the newRow to the current <table>
// element:
table.appendChild(newRow);
// here we find the :last-child of the newly-added row,
// which is the <td> containing the average of the
// averages column:
let averageOfAverage = newRow.querySelector('td:last-child');
// here we set the display of that <td>, if the user wants to
// hide the cell (opts.hideAverageOfAverages is true) then
// we set the display style to 'none'; otherwise (if
// opts.hideAverageOfAverages is anything other than exactly true)
// we set the display to that of 'table-cell':
averageOfAverage.style.display = opts.hideAverageOfAverages === true ? 'none' : 'table-cell';
// and then we add the requisite, user-defined, class-name:
averageOfAverage.classList.add(opts.averageOfAveragesClassName);
});
// at this point we return the Array of <tables> found
// to the calling context if the user wants to have
// use to them for any other reason:
return allTables;
})({
'table': '#myTable, #myOtherStrangelyIdenticalTable',
'hideAverageOfAverages': false,
'rowAverageClassName': 'rowAverage',
'columnAverageClassName': 'columnAverage',
'averageOfAveragesClassName': 'averageOfAverage',
'decimalPlaces': 1
});
表格{
保证金:0自动1米自动;
}
运输署{
宽度:1.5em;
高度:1.5em;
边框:1px实心#000;
文本对齐:居中;
}
平均值{
颜色:红色;
}
平均值{
颜色:柠檬黄;
}
td.columnAverage.rowAverage.averageOfAverage{
颜色:丽贝卡紫;
字体大小:粗体;
}
7.
9
8.
5.
7.
9
6.
6.
8.
7.
9
8.
5.
7.
9
6.
6.
8.
您可以这样做,对行进行迭代,然后首先填充最后一列
更新行的平均列后,迭代第n列并更新平均值
以下是一个示例:
document.onreadystatechange=()=>{
如果(document.readyState==='complete'){
var rows=document.querySelector(“#myTable”).rows;
[]forEach.call(行,(行)=>{
设currentSum=0;
设cells=row.cells;
[]forEach.call(单元格,(currentVal)=>{
currentSum+=parseInt(currentVal.innerText,10);
});
appendElement(行,(currentSum/cells.length).toFixed(1));
});
让columnCount=document.queryselectoral(“tr:n子(1)>td”).length;
让rowContent=document.createElement(“tr”);
let table=document.querySelector(“myTable”);
for(让idx=0;idxtd:n子项(“+(idx+1)+”);
设currentSum=0;
[]forEach.call(列,(列)=>{
currentSum+=parseInt(column.innerText,10);
});
appendElement(行内容,(currentSum/rows.length).toFixed(1))
}
表.appendChild(行内容);
}
};
函数appendElement(父元素、和元素){
让cellEle=document.createElement(“td”);
cellEle.innerText=总和;
cellle.classList.add(“粗体”);
父母、子女(cellEle);
}
.bold{
字体大小:粗体;
}
7.
9
8.
5.
7.
9
6.
6.
8.