JavaScript点击事件中值的添加与移除逻辑问题求助
问题:比赛结果点击切换时球队数据无法正确回滚
我有两个表格,一个用于展示球队对象及其数据,另一个是供用户点击的比赛选项表格,点击后可修改前者的球队数据。首次点击时数据变更正常,但再次点击时无法正确回滚数据:例如点击win单元格时,首次会为主队增加3分和1场胜利,但再次点击时无法扣除对应的分数和胜场。
现有代码示例
数据定义
let teams = [ {name: 'Roma', points: 0, wins: 0, draws: 0, loses: 0}, {name: 'Atalanta', points: 0, wins: 0, draws: 0, loses: 0}, {name: 'Milan', points: 0, wins: 0, draws: 0, loses: 0}, {name: 'Fiorentina', points: 0, wins: 0, draws: 0, loses: 0}, ] let matches = [ // Round 1. {homeName: teams[0].name, teamHome: 0, win: '', draw: '', awayTeamWin: '', teamAway: 1, awayName: teams[1].name}, {homeName: teams[2].name, teamHome: 2, win: '', draw: '', awayTeamWin: '', teamAway: 3, awayName: teams[3].name}, // Round 2. {homeName: teams[0].name, teamHome: 0, win: '', draw: '', awayTeamWin: '', teamAway: 2, awayName: teams[2].name}, {homeName: teams[1].name, teamHome: 1, win: '', draw: '', awayTeamWin: '', teamAway: 3, awayName: teams[3].name}, // Round 3. {homeName: teams[0].name, teamHome: 0, win: '', draw: '', awayTeamWin: '', teamAway: 3, awayName: teams[3].name}, {homeName: teams[1].name, teamHome: 1, win: '', draw: '', awayTeamWin: '', teamAway: 2, awayName: teams[2].name}, ]
分数统计函数
function matchWinnerTeamPoints(matchWinner) { matchWinner.points += 3; matchWinner.wins ++; } function matchLoserTeamPoints(matchLoser) { matchLoser.loses ++; } function matchDrawPoints(teamHome, teamAway) { teamHome.points ++; teamAway.points ++; teamHome.draws ++; teamAway.draws ++; }
比赛表格渲染与点击事件
function createMatchesTable(matchesTableBody, matches) { cleaner(matchesTableBody); // 原代码省略循环逻辑,仅保留关键点击事件部分 let win = bodyRow.insertCell(-1); if (match.win === true) { win.className = 'bg-success'; } win.onclick = (e) => { match.draw = ''; match.awayTeamWin = ''; match.win = !match.win; createMatchesTable(matchesTableBody, matches); matchWinnerTeamPoints(teams[match.teamHome]); matchLoserTeamPoints(teams[match.teamAway]); cleaner(createStandingTable(standingTableBody, teams)); } }
问题根源
- 无回滚逻辑:现有代码只实现了"加分/增加统计"的正向操作,完全没有处理"取消结果时扣除数据"的反向逻辑,导致再次点击时只会继续累加数据。
- 状态判断混乱:
match对象的状态初始值为字符串'',和布尔值true混合使用,容易导致判断错误;且未处理之前可能设置过的其他结果(比如先点了平局,再点主队胜时,没有回滚平局的统计)。
解决方法
1. 新增回滚函数
为每种比赛结果编写对应的反向回滚逻辑,与正向统计函数对应:
// 保留原有正向函数 function matchWinnerTeamPoints(matchWinner) { matchWinner.points += 3; matchWinner.wins++; } function matchLoserTeamPoints(matchLoser) { matchLoser.loses++; } function matchDrawPoints(teamHome, teamAway) { teamHome.points++; teamAway.points++; teamHome.draws++; teamAway.draws++; } // 新增回滚函数 function rollbackWinnerPoints(matchWinner) { matchWinner.points -= 3; matchWinner.wins--; } function rollbackLoserPoints(matchLoser) { matchLoser.loses--; } function rollbackDrawPoints(teamHome, teamAway) { teamHome.points--; teamAway.points--; teamHome.draws--; teamAway.draws--; }
2. 修改点击事件逻辑
遵循先回滚旧状态,再应用新状态的流程,同时统一状态为布尔值:
function createMatchesTable(matchesTableBody, matches) { cleaner(matchesTableBody); // 遍历所有比赛,补充完整循环逻辑 matches.forEach(match => { let bodyRow = matchesTableBody.insertRow(); // 插入主客场队名等其他单元格的逻辑... let win = bodyRow.insertCell(-1); win.textContent = '主队胜'; // 统一用布尔值判断状态 if (match.win === true) { win.className = 'bg-success'; } win.onclick = (e) => { const homeTeam = teams[match.teamHome]; const awayTeam = teams[match.teamAway]; // 第一步:回滚当前比赛已有的结果 if (match.win) { // 当前是选中状态,点击取消,回滚主队胜数据 rollbackWinnerPoints(homeTeam); rollbackLoserPoints(awayTeam); } else if (match.draw) { // 之前是平局,切换为主队胜,先回滚平局数据 rollbackDrawPoints(homeTeam, awayTeam); } else if (match.awayTeamWin) { // 之前是客队胜,切换为主队胜,先回滚客队胜数据 rollbackWinnerPoints(awayTeam); rollbackLoserPoints(homeTeam); } // 第二步:更新比赛状态,清空其他结果 match.draw = false; match.awayTeamWin = false; match.win = !match.win; // 第三步:如果新状态为选中,应用正向统计 if (match.win) { matchWinnerTeamPoints(homeTeam); matchLoserTeamPoints(awayTeam); } // 重新渲染表格 createMatchesTable(matchesTableBody, matches); createStandingTable(standingTableBody, teams); }; // 平局(draw)和客队胜(awayTeamWin)的点击逻辑参考上述实现,注意角色互换 }); }
3. 初始化状态修正
将matches数组中所有结果的初始值改为布尔值false,避免类型判断问题:
let matches = [ // Round 1. {homeName: teams[0].name, teamHome: 0, win: false, draw: false, awayTeamWin: false, teamAway: 1, awayName: teams[1].name}, {homeName: teams[2].name, teamHome: 2, win: false, draw: false, awayTeamWin: false, teamAway: 3, awayName: teams[3].name}, // ...其他比赛项同理修改 ]
内容的提问来源于stack exchange,提问作者Willy Wonka
相关产品推荐
相关产品推荐

