Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中HTML表内容列和行的平均值_Javascript_Html - Fatal编程技术网

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.