JavaScript双点击计数器总计规则定制:特定按钮计数累加实现需求
解决方案
需要实现以下核心逻辑:
- 维护全局总计值,提供更新总计DOM的方法
- 为每个计数器实例标记类型,区分"Verified Videos"和"Document Count"的计数规则
- 修复总计区域的DOM渲染方式,避免使用
document.write
修改后的完整代码
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Click counter</title> <link rel="stylesheet" href="./style.css"> </head> <body> <div class="block-wrapper"> <div class="doctile"> <div class="c-block" data-config-click='{"selectors":{"trigger":".button","target": ".result","reset":".button-reset"}, "type": "document"}'> <b class="result"></b> <button class="button button-primary" type="button"> Document Count </button> <button class="button-reset"> Reset </button> </div> </div> <div class="vidtile"> <div class="c-block" data-config-click='{"selectors":{"trigger":".button","target": ".result","reset":".button-reset"}, "type": "video"}'> <b class="result"></b> <button class="button button-secondary" type="button"> Verified Videos </button> <button class="button-reset"> Reset </button> </div> </div> </div> <span class="totaltile"> <p>Total Units = <span id="total-count">0</span></p> </span> <script src="./script.js"></script> </body> </html>
CSS
body { background: #000000; height: 100vh; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; } .block-wrapper { width: 100vw; display: flex; justify-content: center; margin: auto; } .c-block { margin: 50px; } button, b { display: block; text-align: center; } button { border: none; cursor: pointer; } button:focus { outline: none; } .doctile { background-color: #000000; margin-top: 40px; width: 375px; height: 425px; border-radius: 12px; border: solid; border-color: rgb(170, 170, 170,0.5); display: flex; justify-content: center; margin: 20px; } .vidtile { background-color: #000000; margin-top: 40px; width: 375px; height: 425px; border-radius: 12px; border: solid; border-color: rgb(170, 170, 170,0.5); display: flex; justify-content: center; margin: 20px; } .button { margin-top: 40px; color: rgb(0, 190, 255); padding: 4px 10px; border-radius: 6px; border: solid; border-color: rgb(170, 170, 170,0.5); font-size: 32px; } .button:hover { opacity: 0.9; } .button[disabled] { opacity: 0.7; cursor: not-allowed; } .button-primary { background-color: rgb(85, 85, 85, .4); } .button-secondary { background-color: rgb(85, 85, 85, .4); } .button-reset { background-color: rgb(85, 85, 85, .4); display: block; color: rgb(0, 190, 255); margin: 12px auto 0; font-size: 16px; padding: 4px 56px; border-radius: 6px; border: solid; border-width: 2px; border-color: rgb(170, 170, 170,0.5); } .result { color: rgb(0, 190, 255); font-size: 100px; margin-bottom: 8px; } .totaltile { width: 500px; height: 50px; padding: 4px 10px; border-radius: 6px; border: solid; border-color: rgb(170, 170, 170,0.5); font-size: 32px; display: flex; justify-content: center; margin: auto; } p { color: rgb(0, 190, 255); font-size:25px; margin-top: 10px; }
JavaScript
// 全局总计管理 let totalCount = 0; const totalElement = document.getElementById('total-count'); function updateTotal() { totalElement.textContent = totalCount; } class ClickCount { constructor(obj) { this.triggerNode = obj.triggerNode; this.targetNode = obj.targetNode; this.resetNode = obj.resetNode; this.type = obj.type; // 标记计数器类型:document/video this.count = 0; this.handleClick(); this.handleCount(); } handleClick() { this.triggerNode.addEventListener("click", () => { this.count++; this.handleCount(); // 根据类型处理总计 if (this.type === 'video') { totalCount++; updateTotal(); } else if (this.type === 'document') { // 每9次点击加1 if (this.count % 9 === 0) { totalCount++; updateTotal(); } } }); this.resetNode.addEventListener("click", () => this.handleReset()); } handleCount() { this.targetNode.innerHTML = this.count; } handleReset() { this.count = 0; this.handleCount(); // 注意:如果需要重置时同步调整总计,需额外逻辑,当前需求未提及,故不处理 } } const clickBlock = document.querySelectorAll("[data-config-click]"); clickBlock.forEach((block) => { const config = JSON.parse(block.dataset.configClick); const { trigger, target, reset } = config.selectors; const triggerNode = block.querySelector(trigger); const targetNode = block.querySelector(target); const resetNode = block.querySelector(reset); if (triggerNode && targetNode) { new ClickCount({ triggerNode, targetNode, resetNode, type: config.type // 传递类型参数 }); } });
关键修改点
HTML部分:
- 为每个
c-block的data-config-click添加type字段,标记是document还是video类型 - 将总计区域的
document.write替换为静态<span id="total-count">0</span>,便于动态更新
- 为每个
JavaScript部分:
- 新增全局变量
totalCount和updateTotal方法,负责维护和更新总计显示 - 在
ClickCount类中新增type属性,区分不同计数器的规则 - 点击事件中根据类型处理总计:视频按钮每次点击加1,文档按钮每9次点击加1
- 实例化
ClickCount时传递type参数
- 新增全局变量
CSS部分:无需修改,保持原样式即可
内容的提问来源于stack exchange,提问作者Jon Beckner
相关产品推荐
相关产品推荐

