我有一个HTML表,其中每一列都是其自己的类的一部分。单击列中的单元格时,应将一个新类添加到该单元格(.selected)。同一列中的其他单元格应删除“ .selected”类,以便每列只能有1个单元格成为“ .selected”类的一部分。 为此,我将表中所有元素的classList与单击的单元格“ this”进行比较,在列表匹配时删除该类,然后将其重新添加到单击的单元格中。 这失败了,最终使所有单元格都属于这两个类。
日志显示,对于单击的单元格,classList正确更新(添加,然后删除,然后重新添加)。对于其他单元格,它们不受“ if”条件的影响。 这是完整的HTML文档:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<style>
table {
font-family: google-sans, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 2px solid #48236F;
text-align: center;
padding: 8px;
width: 30%;
}
th {
background-color: grey;
color: white;
border: 2px solid #ffffff;
width: 10%;
}
.option {
color: #48236F;
font-weight: bold;
}
.selected {
background-color: #b7dc90;
}
</style>
<div>Choose your coverage situation</div>
<select id="coverage" onchange="mainFunction()">
<option value="">--Choose below--</option>
<option value="1102">Single</option>
<option value="1610">Couple</option>
<option value="2118">Family</option>
</select><br><br>
<span>Dollars Allocated:  </span>
<span id="dollars_id">0 $</span><br><br>
<table id="display-table">
<tr>
<th></th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
<tr>
<th>Option 1</th>
<td class="col_1" value="10">101</td>
<td class="col_2" value="20">201</td>
<td class="col_3" value="30">301</td>
<tr>
<tr>
<th>Option 2</th>
<td class="col_1">102</td>
<td class="col_2">202</td>
<td class="col_3">302</td>
<tr>
<tr>
<th>Option 3</th>
<td class="col_1">103</td>
<td class="col_2">203</td>
<td class="col_3">303</td>
<tr>
<tr>
<th>Option 4</th>
<td class="col_1">104</td>
<td class="col_2">204</td>
<td class="col_3">304</td>
<tr>
<tr>
<th>Option 5</th>
<td class="col_1">105</td>
<td class="col_2">205</td>
<td class="col_3">305</td>
<tr>
</table>
<br>
<span>Remaining Dollars  </span>
<span id="dollars_left_id">0 $</span><br><br>
<script>
function currencyFormat(num) {
return num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,') + ' $';
}
var dollars_allocated = 0;
var deduct = 0;
var test = 0;
function mainFunction() {
dollars_allocated = Number(document.getElementById("coverage").value);
document.getElementById("dollars_id").innerHTML = dollars_allocated;
var table = document.getElementById('display-table');
var cells = table.getElementsByTagName('td');
for(let cell of cells){
cell.onclick = function() {
var dollars_remaining = dollars_allocated;
// Add the clicked cell to the .selected class
console.log(this.classList);
this.classList.add("selected");
console.log(this.classList);
for (var i of document.getElementsByTagName('td')){
if (i.classList == this.classList){
i.classList.remove("selected");
}
console.log(i.classList);
}
console.log(this.classList);
this.classList.add("selected");
console.log(this.classList);
deduct = deduct + Number(this.innerText);
document.getElementById("dollars_left_id").innerHTML = dollars_remaining - deduct;
}
}
}
window.onload = mainFunction();
</script>
</body>
</html>
我希望控制台日志中只显示15个元素中的1个,成为'.selected'类的一部分。 所选类别显示绿色背景,因此很容易看到错误。
感谢帮助。
编辑
根据zer00ne的出色回答,以下是经过一些调整的最终功能:
1-确保只能单击<td>
个元素
2-“剩余”将“选定”类的所有元素加起来,而不仅仅是目标
3-为每个元素添加了“值”属性,以允许返回值,而与单元格的innerText无关,以提高灵活性。
<script>
const form = document.forms.healthcare;
const table = document.getElementById('display');
const cells = document.getElementsByTagName('td');
form.onchange = dollars;
table.onclick = dollars;
function dollars(e) {
const target = e.target;
const type = e.type;
const fields = form.elements;
const col1 = Array.from(table.querySelectorAll('.col1'));
const col2 = Array.from(table.querySelectorAll('.col2'));
const col3 = Array.from(table.querySelectorAll('.col3'));
if (type === 'change') {
if (target.matches('#coverage')) {
fields.allocated.value = currency(parseFloat(target.value));
}
} else if (type === 'click') {
if (target.matches('.col1')) {
for (let cel1 of col1) {
cel1.classList.remove('selected');
}
} else if (target.matches('.col2')) {
for (let cel2 of col2) {
cel2.classList.remove('selected');
}
} else {
for (let cel3 of col3) {
cel3.classList.remove('selected');
}
}
// Add selected class to clicked cell
if (target.tagName == 'TD'){
target.classList.add('selected');
}
// Add total of selected cells
var totalPremium = 0;
for (let cell of cells){
if (cell.classList.contains('selected')){
totalPremium = totalPremium + parseFloat(cell.getAttribute('value'));
}
}
// Substract totalPremium from the allocated dollars
fields.remaining.value = currency(parseFloat(fields.coverage.value) - parseFloat(totalPremium));
} else {
return false;
}
}
function currency(number, country = 'en-US') {
return (number).toLocaleString(country, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
style: "currency",
currency: "USD"
});
}
</script>
答案 0 :(得分:1)
有很多变化,但是与实际问题有关的变化
“ ...显示15个元素中只有1个元素属于'.selected'类的一部分。”
是要从所有.selected
中删除<td>
,然后将.selected
添加到单击的<td>
中。使用<td>
属性可以轻松确定点击的Event.target
。
for (let cell of cells) {
cell.classList.remove('selected');
}
target.classList.add('selected');
修改
在OP中存在一些冲突的信息:
“ ...,因此每列只能有1个单元格可以成为'.selected'类的一部分。”
不是三个td.selected
而是一个td.selected
-每列一个。
演示1 具有以下行为:
只有一个
td.selected
演示2 具有以下行为:
每列一个
td.selected
,共三个td.selected
const form = document.forms.healthcare;
const table = document.getElementById('display');
form.onchange = dollars;
table.onclick = dollars;
function dollars(e) {
const target = e.target;
const type = e.type;
const fields = form.elements;
const cells = table.querySelectorAll('td');
if (type === 'change') {
if (target.matches('#coverage')) {
fields.allocated.value = currency(parseFloat(target.value));
}
} else if (type === 'click') {
if (target.matches('td')) {
for (let cell of cells) {
cell.classList.remove('selected');
}
target.classList.add('selected');
let deduct = parseFloat(target.textContent);
fields.remaining.value = currency(parseFloat(fields.coverage.value) - deduct);
}
} else {
return false;
}
}
function currency(number, country = 'en-US') {
return (number).toLocaleString(country, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
style: "currency",
currency: "USD"
});
}
:root {
font: 400 small-caps 14px/1.2 Arial
}
table {
border-collapse: collapse;
table-layout: fixed;
width: 100%;
}
td,
th {
border: 2px solid #48236F;
text-align: center;
padding: 8px;
width: 25%;
}
th {
background-color: grey;
color: white;
border: 2px solid #ffffff;
}
td,
output {
font-family: Consolas
}
select {
font: inherit
}
.option {
color: #48236F;
font-weight: bold;
}
.selected {
background-color: #b7dc90;
}
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style></style>
</head>
<body>
<form id='healthcare'>
<label for='coverage'>Choose Your Coverage</label><br>
<select id="coverage">
<option value="">--Coverage--</option>
<option value="1102">Single</option>
<option value="1610">Married</option>
<option value="2118">Dependents</option>
<option value="3728">Married with Dependents</option>
</select><br><br>
<label for='allocated'>Allocated:  </label>
<output id="allocated">0</output><br><br>
<table id="display">
<tr>
<th></th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
<tr>
<th>Option 1</th>
<td>101</td>
<td>201</td>
<td>301</td>
</tr>
<tr>
<th>Option 2</th>
<td>102</td>
<td>202</td>
<td>302</td>
</tr>
<tr>
<th>Option 3</th>
<td>103</td>
<td>203</td>
<td>303</td>
</tr>
<tr>
<th>Option 4</th>
<td>104</td>
<td>204</td>
<td>304</td>
</tr>
<tr>
<th>Option 5</th>
<td>105</td>
<td>205</td>
<td>305</td>
</tr>
</table>
<br>
<label for='remaining'>Remaining:  </label>
<output id="remaining">0</output><br><br>
</form>
<script></script>
</body>
</html>
const form = document.forms.healthcare;
const table = document.getElementById('display');
form.onchange = dollars;
table.onclick = dollars;
function dollars(e) {
const target = e.target;
const type = e.type;
const fields = form.elements;
const col1 = Array.from(table.querySelectorAll('.col1'));
const col2 = Array.from(table.querySelectorAll('.col2'));
const col3 = Array.from(table.querySelectorAll('.col3'));
if (type === 'change') {
if (target.matches('#coverage')) {
fields.allocated.value = currency(parseFloat(target.value));
}
} else if (type === 'click') {
if (target.matches('.col1')) {
for (let cel1 of col1) {
cel1.classList.remove('selected');
}
} else if (target.matches('.col2')) {
for (let cel2 of col2) {
cel2.classList.remove('selected');
}
} else {
for (let cel3 of col3) {
cel3.classList.remove('selected');
}
}
target.classList.add('selected');
fields.remaining.value = currency(parseFloat(fields.coverage.value) - parseFloat(target.textContent));
} else {
return false;
}
}
function currency(number, country = 'en-US') {
return (number).toLocaleString(country, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
style: "currency",
currency: "USD"
});
}
:root {
font: 400 small-caps 14px/1.2 Arial
}
table {
border-collapse: collapse;
table-layout: fixed;
width: 100%;
}
td,
th {
border: 2px solid #48236F;
text-align: center;
padding: 8px;
width: 25%;
}
th {
background-color: grey;
color: white;
border: 2px solid #ffffff;
}
td,
output {
font-family: Consolas;
font-size: 1.1rem;
}
select {
font: inherit
}
.option {
color: #48236F;
font-weight: bold;
}
.selected {
background-color: #b7dc90;
}
<!DOCTYPE html>
<html>
<head>
<title>Healthcare</title>
<style></style>
</head>
<body>
<form id='healthcare'>
<label for='coverage'>Choose Your Coverage</label><br>
<select id="coverage">
<option value="">--Coverage--</option>
<option value="1102">Single</option>
<option value="1610">Married</option>
<option value="2118">Dependents</option>
<option value="3728">Married with Dependents</option>
</select><br><br>
<label for='allocated'>Allocated: </label>
<output id="allocated">0</output><br><br>
<table id="display">
<thead>
<tr>
<th></th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
</thead>
<tbody>
<tr>
<th>Option 1</th>
<td class='col1'>101</td>
<td class='col2'>201</td>
<td class='col3'>301</td>
</tr>
<tr>
<th>Option 2</th>
<td class='col1'>102</td>
<td class='col2'>202</td>
<td class='col3'>302</td>
</tr>
<tr>
<th>Option 3</th>
<td class='col1'>103</td>
<td class='col2'>203</td>
<td class='col3'>303</td>
</tr>
<tr>
<th>Option 4</th>
<td class='col1'>104</td>
<td class='col2'>204</td>
<td class='col3'>304</td>
</tr>
<tr>
<th>Option 5</th>
<td class='col1'>105</td>
<td class='col2'>205</td>
<td class='col3'>305</td>
</tr>
</tbody>
</table>
<br>
<label for='remaining'>Remaining: </label>
<output id="remaining">0</output><br><br>
</form>
<script></script>
</body>
</html>
答案 1 :(得分:0)
在测试条件下使用i.classList.value == this.classList.value
而不是将整个对象与==运算符进行比较。
function currencyFormat(num) {
return num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,') + ' $';
}
var dollars_allocated = 0;
var deduct = 0;
var test = 0;
function mainFunction() {
dollars_allocated = Number(document.getElementById("coverage").value);
document.getElementById("dollars_id").innerHTML = dollars_allocated;
var table = document.getElementById('display-table');
var cells = table.getElementsByTagName('td');
for (let cell of cells) {
cell.onclick = function() {
var dollars_remaining = dollars_allocated;
// Add the .selected class to the clicked cell
this.classList.add("selected");
var clickedCellClasslist = this.classList.value;
for (var i of document.getElementsByTagName('td')) {
if (i.classList.value == clickedCellClasslist) {
i.classList.remove("selected");
}
}
this.classList.add("selected");
deduct = deduct + Number(this.innerText);
document.getElementById("dollars_left_id").innerHTML = dollars_remaining - deduct;
}
}
}
window.onload = mainFunction();
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<style>
table {
font-family: google-sans, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 2px solid #48236F;
text-align: center;
padding: 8px;
width: 30%;
}
th {
background-color: grey;
color: white;
border: 2px solid #ffffff;
width: 10%;
}
.option {
color: #48236F;
font-weight: bold;
}
.selected {
background-color: #b7dc90;
}
</style>
<div>Choose your coverage situation</div>
<select id="coverage" onchange="mainFunction()">
<option value="">--Choose below--</option>
<option value="1102">Single</option>
<option value="1610">Couple</option>
<option value="2118">Family</option>
</select><br><br>
<span>Dollars Allocated:  </span>
<span id="dollars_id">0 $</span><br><br>
<table id="display-table">
<tr>
<th></th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
<tr>
<th>Option 1</th>
<td class="col_1" value="10">101</td>
<td class="col_2" value="20">201</td>
<td class="col_3" value="30">301</td>
</tr>
<tr>
<th>Option 2</th>
<td class="col_1">102</td>
<td class="col_2">202</td>
<td class="col_3">302</td>
</tr>
<tr>
<th>Option 3</th>
<td class="col_1">103</td>
<td class="col_2">203</td>
<td class="col_3">303</td>
</tr>
<tr>
<th>Option 4</th>
<td class="col_1">104</td>
<td class="col_2">204</td>
<td class="col_3">304</td>
</tr>
<tr>
<th>Option 5</th>
<td class="col_1">105</td>
<td class="col_2">205</td>
<td class="col_3">305</td>
</tr>
</table>
<br>
<span>Remaining Dollars  </span>
<span id="dollars_left_id">0 $</span><br><br>
</body>
</html>