在第三个div中显示的两个div的自动方程

时间:2017-12-23 04:13:47

标签: javascript html css arrays

在另一位S.O用户的帮助下,我能够使用JavaScript设置一种“排行榜”。

供参考:this page

作为JS的新手,我在解决问题时遇到了麻烦,如何对其进行编码,以便“平均”列自动显示“平均值”列中的值 - 从等式('得分'除以'计数')。

我知道如果有人可以输入数字的文本字段,然后是计算按钮,我会怎么做呢。

num1 = document.getElementById("score").value;
num2 = document.getElementById("count").value;
document.getElementById("average").innerHTML = num1 / num2;

但我不确定如何对其进行编码,以便页面在加载时自动计算并显示。

我还觉得另一个问题就是每个玩家的得分/计数/平均值的div类名称都是相同的 - 假设它们可能需要ID,我是否正确?

2 个答案:

答案 0 :(得分:1)

将以下代码添加到您的脚本中:

var avgEl = document.querySelectorAll('.average');
   avgEl.forEach(function(el, i){
   var score = el.parentElement.querySelector('.score').innerHTML;
   var count = el.parentElement.querySelector('.count').innerHTML;
   var average = parseFloat(score) * count;
   el.innerHTML = average.toFixed(2);
});

工作代码段



document.addEventListener('DOMContentLoaded', () => {
  let elements = []
  let container = document.querySelector('#innercontain')
  // Add each row to the array
  container.querySelectorAll('.row').forEach(el => elements.push(el))
  // Clear the container
  container.innerHTML = ''
  // Sort the array from highest to lowest
  elements.sort((a, b) => b.querySelector('.score').textContent - a.querySelector('.score').textContent)
  // Put the elements back into the container
  elements.forEach(e => container.appendChild(e))
})

var avgEl = document.querySelectorAll('.average');
avgEl.forEach(function(el, i){
	var score = el.parentElement.querySelector('.score').innerHTML;
  var count = el.parentElement.querySelector('.count').innerHTML;
  var average = parseFloat(score) * count;
  el.innerHTML = average.toFixed(2);
});

#outercontain {
	width: 600px;
	height: auto;
	background-color: #f2f2f2;
	text-align: center;
}

#innercontain {
	position: relative;
	display: inline-block;
	vertical-align: top;
	width:90%;
}

#rank {
	position: relative;
	display: inline-block;
	width: 10%;
}

#titlerow, .row, .ranknumber {
	border-bottom: 1px solid #000;
}

.title {
	position: relative;
	display: inline-block;
	width: 22.5%;
}

.title:first-child {
	width: 10%;
}

.player, .count, .score, .average {
	position: relative;
	display: inline-block;
	width: 25%;
}

.height {height:100%;max-height:45px;line-height:45px;}


.row:nth-child(1), .ranknumber:nth-child(1) {
  background: gold;
}

.row:nth-child(2), .ranknumber:nth-child(2) {
  background: #c0c0c0;
}

.row:nth-child(3), .ranknumber:nth-child(3) {
  background: #cd7f32;
}

<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div id="outercontain">
	<div id="titlerow"><div class="title height">RANK</div><div class="title height">PLAYER</div><div class="title height">SCORE</div><div class="title height">COUNT</div><div class="title height">AVERAGE</div>
    </div>

<div id="rank">
<div class="ranknumber height">1.</div>
<div class="ranknumber height">2.</div>
<div class="ranknumber height">3.</div>
<div class="ranknumber height">4.</div>
<div class="ranknumber height">5.</div>

</div><div id="innercontain">
	<div class="row">
      <div class="player height">Player1</div><div class="score height">310</div><div class="count height">3</div><div class="average height"></div>
	</div>
	<div class="row">
      <div class="player height">Player2</div><div class="score height">458</div><div class="count height">3</div><div class="average height"></div>
	</div>
	<div class="row">
      <div class="player height">Player3</div><div class="score height">423</div><div class="count height">3</div><div class="average height"></div>
	</div>
	<div class="row">
      <div class="player height">Player4</div><div class="score height">985</div><div class="count height">3</div><div class="average height"></div>
	</div>
	<div class="row">
      <div class="player height">Player5</div><div class="score height">567</div><div class="count height">3</div><div class="average height"></div>
	</div>

</div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用一些简单的ES6来计算值。

您的代码的主要问题是您没有将字符串解析为数字。最简单的方法是使用Number构造函数而不使用new关键字。

由于您选择了其他人的答案,我进一步做了以便您可以使用单元格中的值进行计算。

如果单元格以=开头,则将评估等式,将#n替换为同一行中td的索引。细胞被索引1以保持与正常csv的内联。

您可以使用一些基本的电子表格函数或实际的javascript函数,并使用坐标选择器[A1:A4]收集值数组,或者您可以收集确切的单元格值[A1,A2,A3,A4]

  • AVERAGE range - 查找值数组的平均值
  • COUNT范围 - 计算一系列值
  • INT - 将值转换为整数
  • MIN - 找到范围内的最低值
  • MAX - 获取范围内的最高值
  • SUM - 获取范围内所有值的总和

&#13;
&#13;
"use strict"

// get the rows as an array
const rows = [...document.querySelectorAll('tbody tr')]
const table = rows.map(row => [...row.children].map(
  cell => cell.textContent
))
const headers = [...document.querySelectorAll('th')]
  .map(header => ({
      header: header.textContent,
      type: header.dataset.type,
      precision: header.dataset.precision || 2,
      radix: header.dataset.radix || 10
    }))

const parse = (options, x) => {
  switch (options.type) {
    case 'Number':
      return Number(x)
    case 'Float':
      return toFixed(options.precision, x)
    case 'Int':
      return parseInt(x, options.radix || 10)
    default:
      return Number(x)
  }
}

const alfaToInt = 
  cell => cell.charCodeAt(0) - 65

const alfaToNum = x =>
  x.charCodeAt(0) - 65

const zeros = x => [0, 10, 100, 1000, 10000, 100000][x]

const toFixed = (precision, x) =>
  Math.round(Number(x) * zeros(precision)) / zeros(precision)

const AVERAGE = range => SUM(range) / range.length
const COUNT = range => range.length
const INT = x => parseInt(x)
const MIN = range => Math.min(...range)
const MAX = range => Math.max(...range)
const SUM = range => range.reduce((a, b) => a + Number(b), 0)
      
// iterate over the rows
rows.forEach(row => {
  // get the child tds
  const tds = row.querySelectorAll('td')
  // iterate over the tds to find the equations
  tds.forEach((td, j) => {

    const text = td.textContent
    const match = text.match(/\=(.*)/)
    // check if the first character is = followed by anything
    if (match) {
      const equation = match[1]
      // convert the placeholders into their values for the sibling td's
      
      const result = equation
        // get values from a range
        .replace(/\[([A-Z]+[0-9]+):([A-Z]+[0-9]+)\]/g, (_, start, end) => {

          const [_s, startColumn, startRow] = start.match(/([A-Z]+)([0-9]+)/)
          const [_e, endColumn, endRow] = end.match(/([A-Z]+)([0-9]+)/)
          let range
          
          if (startRow == endRow) {
            const length = alfaToNum(endColumn) - alfaToNum(startColumn) + 1
            range = [...rows[startRow - 1].children]
              .slice(alfaToNum(startColumn), length)
              .map(cell => cell.textContent)
          } else if (startColumn === endColumn) {
            range = rows.slice(startRow, endRow).map((row, i) => {
              const index = alfaToNum(startColumn)
              
              return parse(headers[index], row.children[index].textContent)
            })
          }
          return '(' + JSON.stringify(range) + ')'
        })
        .replace(/([A-Z]+)([0-9]+)/g, (_, column, row) => {
          const index = alfaToNum(column)
          return parse(
            headers[index],
            rows[row - 1].children[index].textContent
          )
        })
        // get values in the same row
        .replace(/([A-Z]+)+\$/g, (_, cell) => {
          const index = cell.charCodeAt(0) - 65
          return tds[index].textContent
        })
      
      // set the equations field to the result
      try {
        const precision = headers[j].precision
        td.textContent = toFixed(precision, eval(result))
      } catch (e) {
        // if there is an error in the equation display 'Error'
        td.textContent = `Error: ${e.message}`
      }
    }
  })
})
&#13;
body { font-family: sans-serif }
table { border-collapse: collapse }
thead td { color: #aaa; }
td, th { padding: 0.25em 0.5em }
tbody tr:nth-child(odd) { background: #f7f7f7 }
&#13;
<table border='1'>
  <thead>
    <tr>
      <td>A</td>
      <td>B</td>
      <td>C</td>
      <td>D</td>
    </tr>
    <tr>
      <th data-type="Number">score</th>
      <th data-type="Number">count</th>
      <th data-type="Float" data-precision="2">average</th>
      <th data-type="Number">sum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>=A$/B$</td>
      <td>=A$+B$</td>
    </tr>
    <tr>
      <td>3</td>
      <td>4</td>
      <td>=A$/B$</td>
      <td>=A$+B$</td>
    </tr>
    <tr>
      <td>5</td>
      <td>6</td>
      <td>=A$/B$</td>
      <td>=fail</td>
    </tr>
    <tr>
      <td>=AVERAGE([A1:A3])</td>
      <td>=([B1:B3]).reduce((a,b) => a+b, 0)</td>
      <td>=([C1:C3]).reduce((a,b) => a+b, 0)</td>
      <td>=SUM([A1:C1])</td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;