在另一位S.O用户的帮助下,我能够使用JavaScript设置一种“排行榜”。
供参考:this page
作为JS的新手,我在解决问题时遇到了麻烦,如何对其进行编码,以便“平均”列自动显示“平均值”列中的值 - 从等式('得分'除以'计数')。
我知道如果有人可以输入数字的文本字段,然后是计算按钮,我会怎么做呢。
num1 = document.getElementById("score").value;
num2 = document.getElementById("count").value;
document.getElementById("average").innerHTML = num1 / num2;
但我不确定如何对其进行编码,以便页面在加载时自动计算并显示。
我还觉得另一个问题就是每个玩家的得分/计数/平均值的div类名称都是相同的 - 假设它们可能需要ID,我是否正确?
答案 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;
答案 1 :(得分:0)
您可以使用一些简单的ES6来计算值。
您的代码的主要问题是您没有将字符串解析为数字。最简单的方法是使用Number
构造函数而不使用new
关键字。
由于您选择了其他人的答案,我进一步做了以便您可以使用单元格中的值进行计算。
如果单元格以=
开头,则将评估等式,将#n
替换为同一行中td的索引。细胞被索引1以保持与正常csv的内联。
您可以使用一些基本的电子表格函数或实际的javascript函数,并使用坐标选择器[A1:A4]
收集值数组,或者您可以收集确切的单元格值[A1,A2,A3,A4]
。
AVERAGE
range - 查找值数组的平均值COUNT
范围 - 计算一系列值INT
- 将值转换为整数MIN
- 找到范围内的最低值MAX
- 获取范围内的最高值SUM
- 获取范围内所有值的总和
"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;