当前位置: 首页 > news >正文

练习小项目3:随机正能量语录生成器

你会练到的知识点:

  • 数组的创建和随机访问

  • Math.random() 用法

  • DOM 操作:插入文本

项目效果描述: 

每次点击按钮,会从一个正能量语录列表中随机选一句展示在页面上。 

页面结构(HTML 参考): 

<h2>💡 每日一句正能量</h2>
<button id="quoteBtn">生成语录</button>
<p id="quoteDisplay"></p>

实现步骤(按顺序来):

  1. 创建一个数组,里面存放 5~10 条正能量语录

  2. 获取按钮和显示区域的 DOM 元素

  3. 给按钮绑定点击事件

    • 每次点击时,随机从数组中取一条

    • 将它显示到页面上

✅ 提示小技巧:

  • 随机下标用:Math.floor(Math.random() * quotes.length)

  • 更新文本用 .textContent.innerText

🎯 加分项(选做):

  • 每条语录显示时加一个小 emoji,更有趣

  • 点击按钮时加个简单的文字动画(如 fade-in,可用 CSS)

 实践代码如下: 

JS:

const quotes = ["一想全是问题,一做全是答案","每天进步一点点","允许一切发生","凡事发生,皆有利于我","做人做事,最重要是开心","追随自己内心,不必强求"
]const quoteBtn = document.getElementById('quoteBtn')
const quoteDisplay = document.getElementById('quoteDisplay')quoteBtn.addEventListener('click', () => {const quote = quotes[Math.floor(Math.random() * quotes.length)]quoteDisplay.innerHTML = quotequoteDisplay.classList.remove('fade-in');void quoteDisplay.offsetWidth; // 触发重绘quoteDisplay.classList.add('fade-in');
})

 CSS:

 .fade-in {animation: fadeIn 0.5s ease-in-out;}@keyframes fadeIn {from {opacity: 0;transform: translateY(10px);}to {opacity: 1;transform: translateY(0);}}

额外知识记录:为什么写void quoteDisplay.offsetWidth;可以触发重绘

在这个项目中,我尝试让点击按钮时“励志语句”出现一个淡入的动画。一开始加了 .fade-in 的类名,但发现点击多次时动画不会重新执行。

于是我追问了这个问题,并通过交流和思考,慢慢搞懂了下面这些内容:

我的问题是:

为什么重复添加相同的类名 .fade-in,动画不会重新执行?

我的理解过程是:

  1. 浏览器会把 DOM 操作“合并优化”,不会马上渲染(即等待所有样式操作完成后一起渲染);

  2. 连续 .remove().add() 在同一帧内发生时,会被认为“最终没变”,所以动画不触发;

  3. 要想“重新触发”,需要强迫浏览器中间“渲染一下”——

我看到了这句神奇的代码:

void element.offsetWidth;

一开始不理解为什么这么写,于是继续追问。

后来我发现:

  • offsetWidth 是一个读取元素布局的属性;

  • 访问它时会强制触发浏览器的重绘(Reflow);

访问offsetWidth为什么会触发一次浏览器的“强制重绘(reflow)”??

因为浏览器必须确保你访问到的是最新的、准确的布局信息,所以它被迫先完成之前“还没做”的渲染计算(reflow + repaint)。

简单的说就是当你访问offsetWidth时,这时浏览器就不能偷懒了:

“哦,你要读取我页面上这个元素的真实宽度?那我得把之前那堆样式更新都结算一下,再告诉你正确的值。”

所以它会立刻:

  • 把还没更新的样式应用上(style flush)
  • 计算出最终布局(reflow)
  • 然后才返回准确的 offsetWidth
  • 所以写 void element.offsetWidth 就能让浏览器中间“刷新一次”,让它记住 .fade-in 的移除;

  • 接下来再加回 .fade-in,浏览器就能识别成新的动画了!

为什么加 void

因为我们并不关心这个宽度是多少,只是想强制浏览器“刷新一下渲染状态”。

但加上 void,可以避免警告、让代码更语义化 —— 明确告诉浏览器:

“我只是想让你执行这个读取操作,不需要它的返回值。”


✅ 我最后得出的总结:

  • 动画不重新触发的根本原因:浏览器优化掉了连续的相同 DOM 操作

  • 使用 void element.offsetWidth强制触发一次布局刷新

  • 让动画重置并重新执行

http://www.dtcms.com/a/195328.html

相关文章:

  • C语言—指针4
  • EXCEL在一列数据前统一添加负号
  • 【Manim】使用manim画一个高斯分布的动画
  • 黑马k8s(八)
  • Spring MVC 对 JavaWeb 的优化:从核心组件到注解
  • 使用 LSTM/GRU 预测设备异常的模型
  • 前端 vue 部署 nginx 请求 404
  • MCP概述及MCP Server的使用和实现(谷歌ADK使用MCP Server)
  • P6123 [NEERC 2016] Hard Refactoring 题解
  • Invicti-Professional-V25.5
  • C/C++实践(九)C++二叉搜索树深入讲解
  • 高效批量合并Word文档的工具介绍
  • FC7300 PWM MCAL配置引导
  • 关于计算机系统和数据原子性的联系
  • Redis 五种类型基础操作(redis-cli + Spring Data Redis)
  • 反编译读取.class文件
  • 从微积分到集合论(1630-1910)(历史简介)——第1章——积分技巧(1630-1660)(Kirsti Møller Pedersen)
  • 时源芯微|磁珠
  • PCL 计算一条射线与二次曲面的交点
  • 【Unity】 HTFramework框架(六十五)ScrollList滚动数据列表
  • 显性知识的主要特征
  • HNU工训--计算机串口数据收发与测量
  • 2025年PMP 学习十六 第11章 项目风险管理 (总章)
  • 如何在自动化脚本中向控件输入文本?
  • ohttps开启群晖ssl证书自动更新
  • Leetcode76覆盖最小子串
  • 五月份嵌入式面试总结
  • 锐捷交换机STP环路日志信息解读
  • ODB 的安装及使用
  • 前端实现流式输出《后端返回Markdown格式文本,前端输出类似于打字的那种》