0

0

使用JavaScript实现带权重和总计功能的双按钮点击计数器

霞舞

霞舞

发布时间:2025-11-28 11:44:49

|

644人浏览过

|

来源于php中文网

原创

使用JavaScript实现带权重和总计功能的双按钮点击计数器

本教程将指导您如何使用javascripthtml数据属性,构建一个包含两个独立点击计数器的页面,并实现一个全局总计功能。其中一个计数器每次点击使总计增加1,另一个计数器则按照设定的权重(例如每9次点击使总计增加1)来更新总计。我们将通过扩展现有的`clickcount`类和html配置来达到这一目标,确保代码模块化、易于维护。

教程背景与目标

在网页开发中,我们经常需要实现用户交互的计数功能。本教程将解决一个具体问题:在一个HTML页面上,存在两个独立的点击计数器,每个计数器都有自己的显示区域和重置按钮。在此基础上,我们需要添加一个全局的总计显示区域,该总计的更新规则如下:

  1. 当第一个按钮(例如“Verified Videos”)被点击时,全局总计直接增加1。
  2. 当第二个按钮(例如“Document Count”)的点击次数达到特定倍数(例如9、18、27等)时,全局总计增加1(即每9次点击增加1)。

为了实现这一目标,我们将对现有的JavaScript ClickCount 类进行扩展,并优化HTML结构以传递必要的配置信息。

HTML结构优化:引入配置参数

为了使每个计数器能够灵活地配置其对全局总计的影响,我们将利用HTML的data-*属性来传递额外信息。具体来说,我们将扩展 data-config-click 属性,增加 weight 和 resultElement 两个字段。

  • weight: 用于指定该计数器对总计的权重。如果每次点击总计增加1,则 weight 为1。如果每N次点击总计增加1,则 weight 为N。
  • resultElement: 用于指定全局总计显示元素的CSS选择器,以便JavaScript能够找到并更新它。

此外,我们需要一个专门的HTML元素来显示全局总计。

立即学习Java免费学习笔记(深入)”;

更新后的 HTML (index.html):



  
  Click counter
  


  

Total Units = 0

关键变化说明:

  1. 两个 c-block div 中的 data-config-click 属性都增加了 "weight" 和 "resultElement" 字段。
    • "Document Count" 计数器设置 weight: 9,表示每9次点击总计增加1。
    • "Verified Videos" 计数器设置 weight: 1,表示每次点击总计增加1。
    • resultElement: "#total-units" 指向了页面底部的总计显示元素。
  2. 页面底部添加了一个 span 元素,id="total-units",用于显示全局总计,并初始化为0。

CSS样式(保持不变)

CSS样式主要负责页面的布局和视觉呈现,对于本教程的功能实现没有直接影响,因此可以沿用原有的样式。

Napkin AI
Napkin AI

Napkin AI 可以将您的文本转换为图表、流程图、信息图、思维导图视觉效果,以便快速有效地分享您的想法。

下载

style.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逻辑实现:扩展ClickCount类

核心的逻辑修改将在 script.js 文件中完成。我们将扩展 ClickCount 类,使其能够处理全局总计的更新,并根据配置的 weight 值计算贡献。

更新后的 JavaScript (script.js):

window.onload = () => {
  class ClickCount {
    constructor(obj) {
      this.triggerNode = obj.triggerNode;
      this.targetNode = obj.targetNode;
      this.resetNode = obj.resetNode;
      this.weight = obj.weight; // 新增:权重
      this.resultNode = obj.resultNode; // 新增:全局总计显示节点
      this.count = 0;
      this.handleClick();
      this.handleCount();
    }

    /**
     * 更新全局总计:增加当前计数器的贡献
     * 逻辑:计算当前点击前后的加权贡献差值,并更新总计。
     * 例如,如果weight=9,count从8到9,则加权贡献从0增加到1。
     * 如果count从17到18,则加权贡献从1增加到2。
     */
    increaseTotal() {
      // 获取当前全局总计,如果非数字则默认为0
      let currentTotal = isNaN(this.resultNode.innerHTML)
        ? 0
        : parseInt(this.resultNode.innerHTML);

      // 计算当前点击前,该计数器的加权贡献
      const previousWeightedCount = parseInt(this.count / this.weight);

      // 从总计中减去旧的加权贡献
      currentTotal -= previousWeightedCount;

      // 计算当前点击后(count + 1),该计数器的加权贡献
      const newWeightedCount = parseInt((this.count + 1) / this.weight);

      // 将新的加权贡献加回到总计中
      currentTotal += newWeightedCount;

      // 更新全局总计显示
      this.resultNode.innerHTML = currentTotal;
    }

    /**
     * 更新全局总计:减少当前计数器的贡献(用于重置)
     * 逻辑:计算当前计数器的加权贡献,并从总计中减去。
     */
    decreaseTotal() {
      // 获取当前全局总计,如果非数字则默认为0
      let currentTotal = isNaN(this.resultNode.innerHTML)
        ? 0
        : parseInt(this.resultNode.innerHTML);

      // 计算当前点击数对应的加权贡献
      const weightedCount = parseInt(this.count / this.weight);

      // 从总计中减去该贡献
      currentTotal -= weightedCount;

      // 更新全局总计显示
      this.resultNode.innerHTML = currentTotal;
    }

    /**
     * 处理点击事件
     */
    handleClick() {
      this.triggerNode.addEventListener("click", () => {
        this.increaseTotal(); // 在计数器自身增加前,先更新全局总计
        this.handleCount({
          count: this.count++, // 增加计数器自身点击数
        });
      });
      this.resetNode.addEventListener("click", () => this.handleReset());
    }

    /**
     * 更新计数器自身的显示
     */
    handleCount() {
      this.targetNode.innerHTML = this.count;
    }

    /**
     * 处理重置事件
     */
    handleReset() {
      this.decreaseTotal(); // 在计数器自身重置前,先从全局总计中移除贡献
      this.count = 0; // 重置计数器自身点击数
      this.handleCount();
    }
  }

  // 遍历所有配置了点击计数器的HTML块
  const clickBlock = document.querySelectorAll("[data-config-click]");

  clickBlock.forEach((block) => {
    const config = JSON.parse(block.dataset.configClick);
    // 解构获取所有配置参数,包括新增的 weight 和 resultElement
    const { trigger, target, reset, weight, resultElement } = config.selectors;

    // 获取DOM节点
    const triggerNode = block.querySelector(trigger);
    const targetNode = block.querySelector(target);
    const resetNode = block.querySelector(reset);
    // 获取全局总计显示节点
    const resultNode = document.querySelector(resultElement);

    // 确保关键节点存在,然后创建 ClickCount 实例
    if (triggerNode && targetNode) {
      new ClickCount({
        triggerNode,
        targetNode,
        resetNode,
        resultNode, // 传递全局总计节点
        weight, // 传递权重
      });
    }
  });
};

关键 JavaScript 变化说明:

  1. window.onload 包装: 将所有初始化代码放入 window.onload 事件监听器中,确保DOM完全加载后再执行脚本,避免因元素未加载而导致的错误。
  2. ClickCount 构造函数扩展:
    • 新增 this.weight 和 this.resultNode 属性,用于存储当前计数器的权重和全局总计的DOM节点。
  3. increaseTotal() 方法:
    • 这是实现加权总计的核心。它首先获取当前的全局总计。
    • 然后,它计算当前点击前(this.count)该计数器对总计的贡献 (parseInt(this.count / this.weight)),并从 currentTotal 中减去。
    • 接着,计算点击后(this.count + 1)该计数器对总计的贡献 (parseInt((this.count + 1) / this.weight)),并加回到 currentTotal 中。
    • 这种“先减后加”的逻辑确保了即使连续多次调用 increaseTotal,只要 this.count 未改变,总计也不会重复增加。它准确地反映了在 this.count 增加1时,加权总计是否应该增加1。
    • 最后,更新 resultNode 的 innerHTML。
  4. decreaseTotal() 方法:
    • 用于处理计数器重置时,从全局总计中移除其贡献。
    • 它计算当前 this.count 对应的加权贡献,并直接从 currentTotal 中减去。
  5. handleClick() 方法修改:
    • 在 this.count++ 之前调用 this.increaseTotal(),确保在更新自身计数的同时,也更新全局总计。
  6. handleReset() 方法修改:
    • 在 this.count = 0 之前调用 this.decreaseTotal(),确保在重置自身计数的同时,也从全局总计中移除其贡献。
  7. 初始化逻辑修改:
    • 在 clickBlock.forEach 循环中,从 config.selectors 中解构出 weight 和 resultElement。
    • 使用 document.querySelector(resultElement) 获取全局总计的DOM节点 resultNode。
    • 在创建 ClickCount 实例时,将 resultNode 和 weight 作为参数传递进去。

运行效果与注意事项

完成上述HTML、CSS和JavaScript的修改后,保存文件并在浏览器中打开 index.html。

  • 点击“Verified Videos”按钮,其自身计数会增加,同时页面底部的“Total Units”也会增加1。
  • 点击“Document Count”按钮,其自身计数会增加。每当其计数达到9、18、27等时,“Total Units”会增加1。
  • 每个计数器的“Reset”按钮将重置该计数器,并同时从“Total Units”中减去该计数器之前贡献的加权值。

注意事项:

  • DOM加载顺序: 使用 window.onload 是一个良好的实践,确保在JavaScript尝试访问DOM元素时,这些元素已经存在于文档中。
  • 数据属性的解析: JSON.parse() 用于将 data-config-click 属性中的JSON字符串转换为JavaScript对象。请确保JSON格式正确,否则会导致解析错误。
  • 全局总计的唯一性: resultElement 应该指向一个唯一的元素(例如通过 id 选择器),以便所有计数器都能更新同一个全局总计。
  • 整数除法: parseInt(count / weight) 实现了向下取整的整数除法,这正是计算加权贡献所需的行为。
  • 健壮性: 在 increaseTotal 和 decreaseTotal 方法中,通过 isNaN(this.resultNode.innerHTML) ? 0 : parseInt(this.resultNode.innerHTML) 来获取 currentTotal,增加了代码的健壮性,防止因 resultNode 内容非数字而导致的问题。

总结

通过本教程,我们成功地将两个独立的点击计数器与一个具有复杂加权规则的全局总计功能结合起来。我们利用HTML数据属性实现了灵活的配置,并通过扩展JavaScript类使其具备了管理全局总计的能力。这种模块化和可配置的设计模式在构建复杂的交互式网页应用时非常有用。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

543

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

372

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

727

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

470

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

990

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

654

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

544

2023.09.20

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.7万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.7万人学习

CSS教程
CSS教程

共754课时 | 17.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号