JavaScript实现九九乘法表并解决隔行变色与鼠标交互

许南星
许南星
发布时间:2026-10-14 | 6人浏览过
原创

在使用JavaScript动态生成九九乘法表时,简单的DOM插入往往难以满足复杂的样式需求,如按视觉行或列进行隔行变色,以及实现鼠标悬停交互。本文将深入解析如何通过双重循环构建乘法表结构,利用取模运算(Modulo)配合 if/switch 语句实现多色交替背景,并介绍一种基于坐标属性的网格布局着色法以修正三角排列导致的视觉断行问题。

目标与准备条件

本例旨在通过纯 JavaScript(原生 DOM 操作)实现一个九九乘法表,要求:

  1. 自动计算并插入 $i \times j$ 的结果。
  2. 实现隔行变色,每组三行颜色不同(例如:绿、灰、橙)。
  3. 3.
  4. 支持鼠标滑过当前行变蓝色,离开后恢复原色。
  5. 4.
  6. 对比 if 与 switch 两种逻辑实现方式。
  7. 5.
  8. 解决非矩形矩阵(三角形排列)下的“视觉行”变色对齐问题。

无需引入 jQuery 或其他框架,直接操作 <div> 元素及 style 属性即可达成。

基础实现:生成乘法表结构

首先,我们需要理解乘法表的逻辑:外层循环控制行数(i),内层循环控制列数(j)。为了后续追踪颜色和位置,我们设置一个计数器 cur。

第1步:创建容器并插入内容

在浏览器环境中,我们可以创建 div 元素并赋予其唯一 ID。以下代码演示了最基础的乘法表生成过程,虽然未包含复杂样式,但确立了 DOM 结构的基础。

var cur = 1;
// 外层循环控制行数 i
for(var i=1; i<=9; i++){
    // 内层循环控制列数 j
    for(var j=1; j<=i; j++){
        var sum = i * j;
        var Div = document.createElement("div");
        Div.id = "div" + cur;
        // 此处为简化演示,实际项目中通常配合 CSS 进行绝对或相对定位排版
        Div.style.top = i*35 + 'px';
        Div.style.left = j*105 + 'px';
        cur++;
        Div.innerHTML = j+"*"+i+"="+sum;
        document.body.appendChild(Div);
    }
}

此时页面中已出现乘法表节点,具体视觉效果如下:

核心功能:隔行变色逻辑

乘法表是三角形的,但用户期望的是类似表格的“每三行一组”的视觉隔行效果。这里有两个难点:

1. 顺序变色:按照节点生成的先后顺序,每三个节点换一种颜色。

2. 视觉对齐(进阶):由于第 N 行的节点数量少于第 N+1 行,如果单纯按节点序号取模,视觉上会出现错位的横条。我们将先实现按序号变色的基础版,随后解决错位问题。

方法一:使用 if-else 判断

利用总计数 cur 对 3 取余数(%),根据余数 0、1、2 分别赋值不同的背景色变量。

var cur = 1;
for(var i=1; i<=9; i++){
    for(var j=1; j<=i; j++){
        // ... 省略生成节点代码 ...
        
        var oDiv = document.getElementById("div" + cur);
        var bg = null;
        
        if(cur % 3 == 0){
            bg = "green";
        } else if(cur % 3 == 1){
            bg = "grey";
        } else if(cur % 3 == 2){
            bg = "orange";
        }
        oDiv.style.backgroundColor = bg;
        
        cur++;
    }
}

实现效果如下:

方法二:使用 switch 语句

逻辑完全相同,仅改变分支结构的语法。switch 在处理多值匹配时结构更清晰。

var cur = 1;
for(var i=1; i<=9; i++){
    for(var j=1; j<=i; j++){
        // ... 省略生成节点代码 ...
        
        var oDiv = document.getElementById("div" + cur);
        var bg = null;
        
        switch(cur % 3){
            case 0:
                bg = "green";
                break;
            case 1:
                bg = "grey";
                break;
            case 2:
                bg = "orange";
                break;
        }
        oDiv.style.backgroundColor = bg;
        
        cur++;
    }
}

从运行结果看,switch 版本与 if 版本视觉效果一致:

进阶优化:解决视觉错位与鼠标交互

上述按 cur 序号取模的方法,会导致第3行最后一个元素和第4行第一个元素颜色相同,但在屏幕上它们不在同一水平线上。为了实现真正的“行”隔行变色,或者模拟 100 宫格的布局效果,我们需要引入坐标概念。

原理:自定义属性记录坐标

我们可以给每个 div 添加一个自定义属性(如 data-coord 或这里的 abc),存储其行号和列号的组合。这样就能通过数学公式精确判断它属于哪一组视觉行,或者像网格一样分布。

第2步:结合鼠标悬停交互

除了背景色,还需要实现:鼠标移入当前 div 变为红色(演示用),移出后恢复之前的背景色。这需要保存初始状态。

// 初始化函数示例
function initTable() {
    var cur = 1;
    var bg = null;
    
    for(var i=1; i<=9; i++){
        for(var j=1; j<=i; j++){
            var sum = i*j;
            var Div = document.createElement("div");
            Div.id = "div" + cur;
            Div.style.top = i*35 + 'px';
            Div.style.left = j*105 + 'px';
            // 核心:记录行列坐标,用于复杂排版或精准着色
            Div.setAttribute('coord', i+','+j); 
            
            cur++;
            Div.innerHTML = j+"*"+i+"="+sum;
            document.body.appendChild(Div);
        }
    }
    
    // 统一处理样式着色
    var allDivs = document.getElementsByTagName("div");
    // 注意:此处仅针对刚创建的节点,需排除其他页面可能存在的div,实践中建议限定容器范围
    // 假设 body 中只有我们创建的这些 div,则直接遍历
    for(var k=0; k<allDivs.length; k++){
        var val = allDivs[k].getAttribute('coord');
        // 简单示意:可根据行号 (val.split(',')[0]) 来实现真正的横向隔行
        // 这里沿用之前的顺序逻辑作为演示开关案例
        switch(k % 3){ 
            case 0: bg="green"; break;
            case 1: bg="grey"; break;
            case 2: bg="orange"; break; 
        }
        allDivs[k].style.backgroundColor = bg;
        
        // 绑定鼠标事件
        bindHoverEvent(allDivs[k]);
    }
}

function bindHoverEvent(element) {
    element.onmouseover = function(){
        // 保存当前的背景色
        var defaultBg = this.style.backgroundColor; 
        // 存入临时属性以便恢复
        this.dataset.originalBg = defaultBg;
        // 移入变红
        this.style.backgroundColor = 'blue'; 
    };
    
    element.onmouseout = function(){
        // 恢复保存的颜色
        this.style.backgroundColor = this.dataset.originalBg || ''; 
    };
}

关于坐标定位与布局的关系,如下图所示,若强行排成方形网格(100个单元格),坐标系统将非常规整:

而乘法表截取了对角线部分,形成了三角形状:

使用自定义属性记录坐标后,不仅可以轻松实现隔行变色,还能扩展出任意形状的表格渲染。最终渲染出的带有交互效果的乘法表大致如下(脑补或自行运行代码查看):

代码封装与总结

为了复用性,可以将上述逻辑封装为一个函数,接受参数 m 决定生成到多少乘法表。

function multiTable(m) {
    var cur = 1;
    for(var i=1; i<=m; i++){
        for(var j=1; j<=i; j++){
            var sum = i*j;
            var Div = document.createElement("div");
            Div.id = "div" + cur;
            Div.style.top = i*35 + 'px';
            Div.style.left = j*105 + 'px';
            Div.setAttribute('abc', i+''+j);
            
            cur++;
            Div.innerHTML = j+"*"+i+"="+sum;
            document.body.appendChild(Div);
        }
    }
    
    var oDiv = document.getElementsByTagName("div");
    for(var k=0; k<oDiv.length; k++){
        var val = oDiv[k].getAttribute('abc');
        // 可根据 val 中的行号信息进一步定制颜色逻辑
        switch(k % 3){ 
            case 0: bg="green"; break;
            case 1: bg="grey"; break;
            case 2: bg="orange"; break; 
        }
        oDiv[k].style.backgroundColor = bg;
    }
}

// 调用生成 9x9 乘法表
multiTable(9);

通过以上步骤,我们不仅完成了九九乘法表的数据输出,还掌握了:

  • 如何利用嵌套循环与 DOM API 构建页面结构。
  • 如何使用取模运算实现周期性的视觉样式切换。
  • 如何通过 dataset 或自定义属性缓存状态,实现鼠标交互效果。

以上就是JavaScript实现九九乘法表并解决隔行变色与鼠标交互的详细内容,更多关于JavaScript前端开发与DOM操作的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表