前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【Html.js——效果实现】冰墩墩心情刻画尺(蓝桥杯真题-6182)【合集】

【Html.js——效果实现】冰墩墩心情刻画尺(蓝桥杯真题-6182)【合集】

作者头像
Rossy Yan
发布2025-02-19 10:01:32
发布2025-02-19 10:01:32
4700
代码可运行
举报
运行总次数:0
代码可运行

背景介绍

2022 奥运会满意度调查开始了,冰墩墩作为奥运吉祥物以亲民可爱的形象火遍全球,这次,冰墩墩请你打分,满分 5 分,最低 1 分,快来评分吧!

准备步骤

本题已经内置了初始代码,打开实验环境,目录结构如下:

代码语言:javascript
代码运行次数:0
复制
├── css
│   └── index.css
├── index.html
└── js
    └── index.js

其中:

  • index.html 是主页面。
  • css 是存放页面样式的文件夹。
  • js/index.js 是需要补充代码的 js 文件。

注意:打开环境后发现缺少项目代码,请手动键入下述命令进行下载:

代码语言:javascript
代码运行次数:0
复制
wget https://labfile.oss.aliyuncs.com/courses/16474/dundun.zip && unzip dundun.zip && rm dundun.zip

选中 index.html 右键启动 Web Server 服务(Open with Live Server),让项目运行起来。接着,打开环境右侧的【Web 服务】,就可以在浏览器中看到如下效果:

在初始化的时候拖拽红色心情条,冰墩墩脸上并没有效果


目标效果

请在 js/index.js 文件中补全代码,具体需求如下: 不同心情下的冰墩墩对应类名如下表: 心情:类名不满意.not-satisfied有点不满意.a-little-unsatisfied普通.ordinary满意.satisfied.great

  1. 在初始状态下,冰墩冰墩元素 (class=BingDunDun) 处于不满意状态。
  2. 进度条在不同位置时,通过给冰墩冰墩元素 (class=BingDunDun) 添加对应类名完成不同心情的效果切切换。
  3. 不能修改原有类名和添加多余类名,例:满意状态下的对应该是 class=BingDunDun satisfied

完成后效果如下:


要求规定

  • 请按照给出的步骤操作,切勿修改默认提供的文件名称、文件夹路径等。
  • 满足需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动检测。

判分标准

  • 本题完全实现题目目标得满分,否则得 0 分。

通关代码✔️

代码语言:javascript
代码运行次数:0
复制
const range = document.getElementById("range"); // 获取进度条 
const BingDunDun = document.querySelector(".BingDunDun");  //获取冰墩墩元素

// 初始状态下,冰墩墩处于不满意状态
BingDunDun.classList.add("not-satisfied");

range.onchange = (e) => {
    let value = Number(e.target.value); // value 进度条的值
    // 移除冰墩墩元素上所有可能的心情类名
    BingDunDun.classList.remove("not-satisfied", "a-little-unsatisfied", "ordinary", "satisfied", "great");

    // 根据进度条的值添加对应的心情类名
    if (value < 20) {
        BingDunDun.classList.add("not-satisfied");
    } else if (value < 40) {
        BingDunDun.classList.add("a-little-unsatisfied");
    } else if (value < 60) {
        BingDunDun.classList.add("ordinary");
    } else if (value < 80) {
        BingDunDun.classList.add("satisfied");
    } else {
        BingDunDun.classList.add("great");
    }
};

代码解析📑

一、HTML 部分

代码语言:javascript
代码运行次数:0
复制
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>2022奥运会满意度调查-冰墩墩心情刻度尺</title>
  <link rel="stylesheet" type="text/css" href="css/index.css" />
</head>

<body>
  <div id="app">
    <!-- 冰墩墩绘制区域 -->
    <div class="BingDunDun">
      <div class="body"></div>
      <div class="ear1"></div>
      <div class="ear2"></div>
      <div class="eye1"></div>
      <div class="eye2"></div>
      <div class="face c_blue"></div>
      <div class="face c_red"></div>
      <div class="face c_purple"></div>
      <div class="face c_yellow"></div>
      <div class="face c_green"></div>
      <div class="nose"></div>
      <div class="mouse"></div>
      <div class="leg1"></div>
      <div class="leg2"></div>
      <div class="arm1"></div>
      <div class="arm2" id="armStyle"></div>
      <div class="logo"></div>
    </div>
    <!-- 进度条 -->
    <div class="box">
      <h1>2022奥运会满意度调查</h1>
      <div class="diyRange">
        <input type="range" max="100" min="0" step="25" value="0" id="range" class="range" />
        <span class="gray"></span>
        <span class="gray1"></span>
        <span class="gray2"></span>
        <span class="gray3"></span>
        <span class="gray4"></span>
      </div>
      <div class="ditText">
        <span>不满意</span>
        <span>有点不满意</span>
        <span>普通</span>
        <span>满意</span>
        <span>棒</span>
      </div>
    </div>
  </div>
  <script src="./js/index.js"></script>
</body>

</html>

1. 文档声明与头部信息

  • <!DOCTYPE html>:声明文档类型为 HTML5。
  • <meta charset="utf-8" />:设置字符编码为 UTF - 8,确保页面能正确显示各种字符。
  • <title>2022奥运会满意度调查-冰墩墩心情刻度尺</title>:设置页面标题,显示在浏览器标签栏。
  • <link rel="stylesheet" type="text/css" href="css/index.css" />:引入外部 CSS 文件,用于设置页面样式。

2. 主体部分

  • <div id="app">:作为整个页面内容的容器。
  • <div class="BingDunDun">:冰墩墩的绘制区域,包含多个子元素,用于构建冰墩墩的各个部分,如身体、耳朵、眼睛等。
  • <div class="box">:进度条及其相关说明的容器。
    • <h1>2022奥运会满意度调查</h1>:显示调查标题。
    • <input type="range" max="100" min="0" step="25" value="0" id="range" class="range" />:创建一个范围输入框(进度条),最小值为 0,最大值为 100,步长为 25,初始值为 0。
    • <span class="gray"></span><span class="gray4"></span>:用于装饰进度条的灰色圆点。
    • <div class="ditText">:包含五个 <span> 元素,分别显示不同的满意度描述,如 “不满意”“有点不满意” 等。

3. 脚本引入

  • <script src="./js/index.js"></script>:引入外部 JavaScript 文件,用于实现进度条与冰墩墩心情的交互逻辑。

二、CSS 部分

代码语言:javascript
代码运行次数:0
复制
* {
	margin: 0;
	padding: 0;
}

body {
	background-color: #5D75B3;
	color: #000000;
	display: flex;
	justify-content: center;
	align-items: center;
}

.BingDunDun {
	width: 600px;
	height: 500px;
	position: relative;  
}

.body {
	width: 362px;
	height: 410px;
	border: 8px solid #393939;
	border-radius: 88% 88% 62% 68% / 82% 82% 95% 84%;
	position: absolute;
	left: 109px;
	top: 10px;
	background: #fff;
}

.ear1,
.ear2 {
	width: 81px;
	height: 115px;
	background-color: #393939;
	border-radius: 50%;
	position: absolute;
	z-index: -1;
}

.ear1 {
	left: 150px;
	top: 16px;
	transform: rotate(-10deg);
}

.ear2 {
	left: 362px;
	top: 18px;
	transform: rotate(10deg);
}

/* 眼睛 */

.eye1,
.eye2 {
	background-color: #393939;
	width: 83px;
	height: 115px;
	border-radius: 50%;
	position: absolute;
}

.eye1 {
	left: 185px;
	top: 102px;
	transform: rotate(45deg);
}

.eye2 {
	left: 329px;
	top: 102px;
	transform: rotate(-45deg);
}

.eye1:before,
.eye2:before {
	content: "";
	width: 40px;
	height: 40px;
	border: #fff 5px solid;
	border-radius: 100%;
	position: absolute;
}
.eye1:before {
	right: 10px;
	top: 22px;
}

.eye2:before {
	left: 10px;
	top: 22px;
}

.eye1:after,
.eye2:after {
	content: "";
	width: 10px;
	height: 10px;
	background: #9b9b9b;
	border-radius: 100%;
	position: absolute;
}

.eye1:after {
	right: 27px;
	top: 31px;
}

.eye2:after {
	left: 41px;
	top: 44px;
}

.face {
	position: absolute;
	border-radius: 48% 48% 44% 49%/ 53% 54% 45% 47%;
}

.c_blue {
	border: #6bcdf3 5px solid;
	width: 280px;
	height: 224px;
	left: 150px;
	top: 58px;
}
.c_red {
	border: #af2350 5px solid;
	width: 287px;
	height: 233px;
	left: 146px;
	top: 53px;
}
.c_purple {
	border: #5d75b3 5px solid;
	width: 295px;
	height: 240px;
	left: 142px;
	top: 50px;
}

.c_yellow {
	border: #ffc346 5px solid;
	width: 305px;
	height: 248px;
	left: 137px;
	top: 45px;
}

.c_green {
	border: #7fcb58 5px solid;
	width: 313px;
	height: 256px;
	left: 133px;
	top: 41px;
}

.nose {
	position: absolute;
	left: 284px;
	top: 167px;
	width: 28px;
	height: 18px;
	background-color: #333333;
	border-radius: 42px 42px 60px 61px/ 30px 30px 50px 46px;
}

.mouse {
	position: absolute;
	left: 265px;
	top: 185px;
	width: 68px;
	height: 25px;
	border-radius: 48%;
	border: #393939 7px solid;
	border-top: none;
	border-left: 0;
	border-right: 0;
	
}
.leg1,
.leg2 {
	background: #333;
	position: absolute;
	width: 83px;
	height: 80px;
	border-radius: 0 0 30px 30px;
	z-index: -1;
}

.leg1 {
	left: 187px;
	top: 403px;
}

.leg2 {
	left: 328px;
	top: 403px;
}

.leg1::before,
.leg2:before {
	content: "";
	width: 43px;
	height: 30px;
	position: absolute;
	background: #363636;
	border-radius: 30px;
}

.leg1:before {
	bottom: 0;
	right: -3px;
}

.leg2:before {
	bottom: 0;
	left: -3px;
}

.arm1,
.arm2 {
	background: #333;
	position: absolute;
	z-index: -1;
}

.arm1 {
	width: 75px;
	height: 118px;
	left: 64px;
	top: 224px;
	transform: rotate(45deg);
	border-radius: 24% 69% 68% 76%/ 53% 95% 40% 52%;
}

.arm2 {
	width: 75px;
	height: 148px;
	left: 444px;
	top: 204px;
	transform: rotate(135deg);
	border-radius: 56% 62% 98% 6%/ 40% 46% 80% 58%;
}

.arm2:before {
	content: "";
	width: 16px;
	height: 24px;
	background: #bc242c;
	position: absolute;
	border-top-left-radius: 50%;
	border-top-right-radius: 50%;
	transform: rotate(45deg);
	left: 32px;
	top: 20px;
}

.arm2:after {
	content: "";
	width: 16px;
	height: 24px;
	background: #bc242c;
	position: absolute;
	border-top-left-radius: 50%;
	border-top-right-radius: 50%;
	transform: rotate(-45deg);
	left: 26px;
	top: 20px;
}

.logo {
	width: 70px;
	height: 100px;
	background-size: cover;
	position: absolute;
	left: 265px;
	top:310px
}
 
.box {
	height: 100px;
	max-width: 450px;
	width: 100%;
	background-color: whitesmoke;
	border-radius: 5px;
	padding: 25px; 
	margin: -15px auto;
	box-shadow: 0 2px 10px 1px bisque; 
	text-align: center;
}
.diyRange { 
	padding: 10px 0;
  position: relative;
}
.ditText {
	width: 450px;  
	position: relative; 
}
.ditText > span {
	position: absolute; 
}
.ditText > span:nth-of-type(1) {
	left: 10px;
}
.ditText > span:nth-of-type(2) {
	left: 90px;
}
.ditText > span:nth-of-type(3) {
	left: 210px;
}
.ditText > span:nth-of-type(4) {
	left: 306px;
}
.ditText > span:nth-of-type(5) {
	left: 405px;
}
.range {
    position:relative ;
    z-index: 100;
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
    outline: 0;
    background-color: transparent;
    width: 400px;
}
.range::-webkit-slider-runnable-track {
    height: 4px;
    background: #eee;
}
[type="range" i]::-webkit-slider-container {
    height: 20px;
    overflow: hidden;
}
.range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: #f44336;
    border: 1px solid transparent;
    margin-top: -8px;
    border-image: linear-gradient(#f44336,#f44336) 0 fill / 8 20 8 0 / 0px 0px 0 2000px;
}

.mouseStyleInit {
	top: 185px;
	height: 25px;
	border-radius: 48%;
}
@keyframes jump { 
	50% {
		transform: translateY(-20px);
	} 
}

.gray,
.gray1,
.gray2,
.gray3,
.gray4 {
position: absolute;
display: inline-block;
width: 20px;
height: 20px;
background-color: #e1e2ec;
border-radius: 50%;
z-index: 1;
}
.gray {
left: 24px;
top: 10px;
}
.gray1 {
left: 120px;
top: 10px;
}

.gray2 {
left: 215px;
top: 10px;
}

.gray3 {
left: 310px;
top: 10px;
}
.gray4 {
left: 405px;
top: 10px;
}

.not-satisfied .arm2,.a-little-unsatisfied .arm2,.ordinary.arm2, .satisfied .arm2 {
	left: 444px;
	top: 204px;
	transform: rotate(135deg);
}
/* 不满意 */
.not-satisfied .mouse {
	height: 80px!important;
	transform: rotate(180deg);
	top: 195px!important;;
}
/* 有点不满意 */
.a-little-unsatisfied .mouse{
	height: 40px!important;
	top: 215px!important;;
	transform: rotate(180deg);
}
/* 普通 */
.ordinary .mouse{
	height: 25px!important;
	border-radius: 20%!important;
	top: 185px!important;
}

/* 满意 */
.satisfied  .mouse{
	height: 25px!important;
}

/* 棒 */
.great{
	animation: jump 0.5s infinite
}
.great .mouse{
	height : 70px!important;
}

.great .arm2{
	left: 463px;
	top: 142px;
	transform: rotate(37deg);
}

1. 满意度描述文字样式

  • .ditText:设置包含满意度描述文字的容器宽度和定位方式。
  • .ditText > span:对每个描述文字元素进行绝对定位。
  • .ditText > span:nth - of-type(n):分别设置每个描述文字元素的水平位置,使其均匀分布在进度条下方。

2. 自定义范围输入框(进度条)样式

  • .range:设置进度条的基本样式,包括去除默认样式、设置宽度和背景透明等。
  • .range::-webkit - slider - runnable - track:设置进度条轨道的高度和背景颜色。
  • [type="range" i]::-webkit - slider - container:设置进度条容器的高度和溢出处理。
  • .range::-webkit - slider - thumb:设置进度条滑块的样式,包括大小、颜色和边框等。

3. 嘴巴初始样式

  • .mouseStyleInit:定义冰墩墩嘴巴的初始样式,包括位置、高度和圆角。

4. 跳跃动画

  • @keyframes jump:定义一个名为 jump 的动画,在 50% 的时间点,冰墩墩向上移动 20px,实现跳跃效果。

5. 进度条上的灰色圆点样式

  • .gray.gray4:设置进度条上五个灰色圆点的样式,包括位置、大小、颜色和圆角。

6.不同心情下的样式

  • .not - satisfied .arm2, .a - little - unsatisfied .arm2, .ordinary.arm2, .satisfied .arm2:设置不满意、有点不满意、普通和满意这几种心情下冰墩墩手臂的位置和旋转角度。
  • .not - satisfied .mouse:设置不满意心情下冰墩墩嘴巴的高度、旋转角度和位置。
  • .a - little - unsatisfied .mouse:设置有点不满意心情下冰墩墩嘴巴的高度、旋转角度和位置。
  • .ordinary .mouse:设置普通心情下冰墩墩嘴巴的高度、圆角和位置。
  • .satisfied .mouse:设置满意心情下冰墩墩嘴巴的高度。
  • .great:设置 “棒” 这种心情下冰墩墩元素应用 jump 动画,使其不断跳跃。
  • .great .mouse:设置 “棒” 这种心情下冰墩墩嘴巴的高度。
  • .great .arm2:设置 “棒” 这种心情下冰墩墩手臂的位置和旋转角度。

三、JavaScript 部分

代码语言:javascript
代码运行次数:0
复制
const range = document.getElementById("range"); // 获取进度条 
const BingDunDun = document.querySelector(".BingDunDun");  //获取冰墩墩元素

// 初始状态下,冰墩墩处于不满意状态
BingDunDun.classList.add("not-satisfied");

range.onchange = (e) => {
    let value = Number(e.target.value); // value 进度条的值
    // 移除冰墩墩元素上所有可能的心情类名
    BingDunDun.classList.remove("not-satisfied", "a-little-unsatisfied", "ordinary", "satisfied", "great");

    // 根据进度条的值添加对应的心情类名
    if (value < 20) {
        BingDunDun.classList.add("not-satisfied");
    } else if (value < 40) {
        BingDunDun.classList.add("a-little-unsatisfied");
    } else if (value < 60) {
        BingDunDun.classList.add("ordinary");
    } else if (value < 80) {
        BingDunDun.classList.add("satisfied");
    } else {
        BingDunDun.classList.add("great");
    }
};

1. 获取元素

  • const range = document.getElementById("range");:通过 id 获取进度条元素,后续可以监听其值的变化。
  • const BingDunDun = document.querySelector(".BingDunDun");:通过类名获取冰墩墩元素,用于后续动态修改其样式类。

2. 设置初始状态

  • BingDunDun.classList.add("not-satisfied");:在页面加载完成后,给冰墩墩元素添加 not-satisfied 类名,使其初始状态呈现为 “不满意” 的表情,这是根据 CSS 中定义的 .not-satisfied 相关样式来实现外观展示的。

3. 监听进度条变化事件

  • range.onchange = (e) => {...}:为进度条元素绑定 change 事件监听器。当用户拖动进度条,改变其值时,会触发这个箭头函数。
  • let value = Number(e.target.value);:在事件处理函数中,首先获取当前进度条的值,并将其转换为数字类型,存储在 value 变量中,方便后续根据该值进行逻辑判断。

4. 移除已有心情类名

  • BingDunDun.classList.remove("not-satisfied", "a-little-unsatisfied", "ordinary", "satisfied", "great");:每次进度条值改变时,先移除冰墩墩元素上所有与心情相关的类名。这样做是为了避免多个心情类名同时存在于元素上,保证每次只应用一个心情状态对应的样式。

5. 根据进度条值添加对应心情类名

  • 通过一系列的 if - else if - else 条件判断语句,根据进度条的当前值 value 来决定给冰墩墩元素添加哪个心情类名:
  • value < 20 时,添加 not-satisfied 类名,冰墩墩呈现 “不满意” 的表情。
  • 20 <= value < 40 时,添加 a-little-unsatisfied 类名,冰墩墩呈现 “有点不满意” 的表情。
  • 40 <= value < 60 时,添加 ordinary 类名,冰墩墩呈现 “普通” 的表情。
  • 60 <= value < 80 时,添加 satisfied 类名,冰墩墩呈现 “满意” 的表情。
  • value >= 80 时,添加 great 类名,冰墩墩呈现 “棒” 的表情,同时会触发 CSS 中定义的跳跃动画。

四、工作流程▶️

  1. 页面加载阶段
    • 浏览器解析 HTML 文件,构建 DOM 树,同时加载外部 CSS 文件和 JavaScript 文件。
    • HTML 中的元素按照结构进行布局,冰墩墩的各个部分(身体、耳朵、眼睛等)根据 CSS 样式规则进行绘制,进度条及其相关说明也显示在页面上。
    • JavaScript 代码开始执行,获取进度条元素和冰墩墩元素,然后给冰墩墩元素添加 not-satisfied 类名,使冰墩墩初始状态为 “不满意” 表情。
  2. 用户交互阶段
    • 用户拖动进度条,改变其值。
    • 进度条的 change 事件被触发,JavaScript 中的事件处理函数开始执行。
    • 事件处理函数首先获取进度条的当前值,接着移除冰墩墩元素上所有与心情相关的类名。
    • 根据进度条的值,通过条件判断给冰墩墩元素添加对应的心情类名。
  3. 样式更新阶段
    • 当冰墩墩元素的类名发生变化后,浏览器会根据新的类名重新计算并应用 CSS 样式。
    • 例如,如果添加了 great 类名,冰墩墩的嘴巴和手臂样式会按照 .great .mouse.great .arm2 的规则进行更新,同时冰墩墩元素会开始执行 jump 动画,从而实现冰墩墩心情随着进度条值变化而改变的效果。

通过 HTML 提供页面结构、CSS 定义样式和动画、JavaScript 实现交互逻辑,三者协同工作,完成了冰墩墩心情刻度尺的效果展示。


测试结果👍

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景介绍
  • 准备步骤
  • 目标效果
  • 要求规定
  • 判分标准
  • 通关代码✔️
  • 代码解析📑
    • 一、HTML 部分
    • 二、CSS 部分
    • 三、JavaScript 部分
  • 测试结果👍
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档