首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Html.js——Bug修复】找回连接的奇幻之旅(蓝桥杯真题-18559)【合集】

【Html.js——Bug修复】找回连接的奇幻之旅(蓝桥杯真题-18559)【合集】

作者头像
Rossy Yan
发布2025-05-31 15:02:16
发布2025-05-31 15:02:16
12600
代码可运行
举报
运行总次数:0
代码可运行

背景介绍

在网络世界中,突然间失去了所有的连接。作为勇敢的冒险者,你将踏上一段惊险刺激的旅程,穿越充满谜题和挑战的网络景观,与神秘的网络幽灵对抗,解开断网之谜,找回失去的连接,带领人们重返数字世界。准备好迎接这场奇幻之旅吗?

准备步骤

开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:

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

其中:

  • index.html 是主页面。
  • css 是样式文件夹。
  • images 是图片文件夹。
  • effect.gif 是项目最终完成的效果图。
  • js/index.js 是待补充的 js 文件。

在浏览器中预览 index.html 页面效果如下:

目标效果

请在 js/index.js 文件中补充 resetableOnce 函数,实现在接收相同的函数时只执行一次。

函数返回值说明:

resetableOnce 函数的返回值为一个对象 ,格式为 :{runOnce:func, reset:func},对应说明如下:

  • runOnce:一个函数,用于执行包装后的函数 fn。当第一次调用 runOnce 时,它将执行 fn 函数,并将结果保存,之后的每次调用将直接返回之前计算的结果。注意:如果传入的函数(fn)不是同一个函数,则 resetableOnce 函数重新执行
  • reset :一个函数,用于重置包装后的函数的状态。调用 reset 后可以让下一次调用 runOnce 时,再次执行 fn 函数。

函数使用示例如下:

代码语言:javascript
代码运行次数:0
运行
复制
// 测试用例 1:resetableOnce(fn) fn 有参数的情况
// 定义一个加法函数
function addNumbers(a, b) {
  return a + b;
}

const test1 = resetableOnce(addNumbers);
console.log(test1.runOnce(2, 3)); // 输出: 5
console.log(test1.runOnce(4, 5)); // 第二次调用不会执行加法操作,返回上次执行的值,输出: 5

// 重置 once
test1.reset();
console.log(test1.runOnce(4, 5)); // 因为重置,addNumbers 再次执行,输出: 9

// 测试用例 2:resetableOnce(fn) fn 无参数的情况
let a = 10;
let fn = () => {
  return a = a + 1;
};
const test2 = resetableOnce(fn); // 传入了不同的函数,之前的 once 不针对此函数生效。
console.log(test2.runOnce()); //输出 11
console.log(test2.runOnce()); // 输出 11
test2.reset();
console.log(test2.runOnce()); // 输出 12

最终效果可参考文件夹下面的 gif 图,图片名称为 effect.gif(提示:可以通过 VS Code 或者浏览器预览 gif 图片)。

要求规定

  • 请勿修改 js/index.js 文件外的任何内容。
  • 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成无法判题通过。

判分标准

  • 传入同一函数满足需求能正确运行,得 5 分。
  • 本题完全实现题目目标得满分。

通关代码✔️

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 定义一个可重置的一次性函数
 * @param {func} fn 要作用的函数
 * @returns {object} {runOnce:func, reset:func } 
 */
function resetableOnce(fn) {
    // 存储上次传入的函数
    let lastFn = null;
    // 存储函数执行结果
    let result = null;
    // 标记函数是否已经执行过
    let hasExecuted = false;

    function runOnce() {
        if (lastFn!== fn) {
            // 如果传入的函数和上次不同,重置状态
            lastFn = fn;
            hasExecuted = false;
        }
        if (!hasExecuted) {
            // 如果函数还未执行过,执行函数并保存结果
            result = fn.apply(this, arguments);
            hasExecuted = true;
        }
        return result;
    }

    function reset() {
        // 重置执行标记,让下一次调用 runOnce 时再次执行 fn 函数
        hasExecuted = false;
    }

    return { runOnce, reset };
}

// 以下代码为检测需要,请勿删除

try {
    module.exports = resetableOnce;
} catch (e) {}

代码解析📑

一、HTML 部分

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>找回连接的奇幻之旅</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <!-- 网络连接错误页面 -->
  <div class="page_error">
    <main>
      <!-- 错误图标 -->
      <img src="./images/error.png" alt="" width="72px" height="72px" style="margin-bottom: 20px;">
      <!-- 错误标题 -->
      <h2>未连接到互联网</h2>
      <!-- 错误提示信息 -->
      <p>
        <span>请试试以下方法:</span>
        <!-- 解决网络问题的建议列表 -->
        <ul>
          <li>检查网线、调制解调器和路由器</li>
          <li>重新连接到 Wi-Fi 网络</li>
        </ul>
      </p>
      <!-- 错误代码 -->
      <p style="font-size: 12px;margin-top: 12px;">ERR_INTERNET_DISCONNECTED</p>

      <!-- 重新连接网络按钮 -->
      <button id="reconnect">
        点击重新连接网络
      </button>

    </main>
    <!-- 显示连接结果的区域 -->
    <div id="result"></div>
  </div>

  <!-- 网络连接成功后的页面 -->
  <div class="page">
    <!-- 页面顶部的图片区域 -->
    <div class="webz">
      <img src="./images/webz.png">
    </div>
    <!-- 报名按钮 -->
    <button class="btn">马上报名</button>
    <!-- 备考路径按钮 -->
    <button class="btn-bk">备考路径</button>
    <!-- 页面内容区域 -->
    <div class="content">
      <!-- 标题图片 -->
      <img src="./images/title.svg" class="block mt-40 mx-auto">
      <!-- 背景图片 -->
      <img src="./images/bg.svg" alt="">
    </div>
  </div>

  <!-- 引入 JavaScript 文件 -->
  <script src="./js/index.js"></script>
  <script>
    const lintier = 2000; // 重连成功后页面的跳转时间
    const reconnect = document.getElementById('reconnect')
    const page = document.querySelector('.page')
    const page_error = document.querySelector('.page_error')
    var tryCount = 0
    let clickEvent = resetableOnce(() => {
      retry(handleLink, 5, 400).then(res => {
        result.innerHTML += `<p>${res}</p>`;
        let flag=false
        // 测试用例 1:resetableOnce(fn) fn 有参数的情况
        // 定义一个加法函数
        function addNumbers(a, b) {
          return a + b;
        }
        const test1 = resetableOnce(addNumbers);
        let one=test1.runOnce(2, 3)
        let two=test1.runOnce(4, 5)
        if(one===two){flag=true}else{flag=false}
        // 重置 once
        test1.reset();
        // 测试用例 2:resetableOnce(fn) fn 无参数的情况
        let a = 10;
        let fn = () => {
          return a = a + 1;
        };
        const test2 = resetableOnce(fn); // 传入了不同的函数,之前的 once 不针对此函数生效。
        let three=test2.runOnce()
        let four=test2.runOnce()
        if(three===four){flag=true}else{flag=false}
        test2.reset();
        let five=test2.runOnce()
        if(five!=four){flag=true}else{flag=false}
        if(flag){
            setTimeout(() => {
              page_error.style.display = 'none'
              page.style.display = 'flex'
            }, lintier)
        }
      }).catch(err => {
        reconnect.innerText = '点击重新连接网络'
        clickEvent.reset()
        result.innerHTML += `<p>${err}</p>`;
      })
    })
    reconnect.onclick = clickEvent.runOnce

    function handleLink() {
      reconnect.innerText = '已经在尝试连接网络...'
      tryCount++
      result.innerHTML += `<p>尝试重连${Date.now()}<p/>`;
      return new Promise((resolve, reject) => {
        let success = tryCount > 7; // 尝试7次以上将重连成功
        if (success) {
          resolve('网络连接成功');
        } else {
          reject('网络连接失败');
        }
      });
    }
    async function retry(operation, maxAttempts, delayBetweenRetries) {
      for (let attempt = 1; attempt <= maxAttempts; attempt++) {
        try {
          // 执行异步操作
          const result = await operation();
          return result; // 如果成功,返回结果
        } catch (error) {
          if (attempt < maxAttempts) {
            console.log(`第 ${attempt} 次尝试重连. 在 ${delayBetweenRetries}ms 后重试...`);
            await new Promise((resolve) => setTimeout(resolve, delayBetweenRetries));
          } else {
            throw error; // 如果达到最大尝试次数仍然失败,抛出错误
          }
        }
      }
    }
  </script>
</body>

</html>

功能概述

  • 此 HTML 文件构建了一个包含网络连接错误页面和网络连接成功页面的网页。用户可以点击 “点击重新连接网络” 按钮尝试重新连接网络,页面会显示连接结果,连接成功后会跳转到成功页面。

详细解释

  1. 头部信息:设置字符编码、视口,引入 CSS 样式文件。
  2. 网络连接错误页面(page_error:包含错误图标、标题、解决建议列表、错误代码、重新连接按钮和显示连接结果的区域。
  3. 网络连接成功页面(page:包含顶部图片、报名和备考路径按钮以及页面内容图片。
  4. JavaScript 代码
    • 定义了重连成功后页面跳转的时间 lintier
    • 使用 resetableOnce 函数包装点击事件处理函数,确保点击事件只执行一次。
    • handleLink 函数模拟网络连接尝试,尝试 7 次以上认为连接成功。
    • retry 函数用于重试网络连接操作,最多尝试 maxAttempts 次,每次尝试间隔 delayBetweenRetries 毫秒。

二、CSS 部分

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

.page_error {
  width: 100vw;
  height: 100vh;
  padding-top: 100px;
  display: flex;
  justify-content: center;
}

#result{
  margin: 80px;
}

h2 {
  margin-bottom: 16px;
  font-size: 24px;
  color: #202124;
  line-height: 1.5;
}

p,
li {
  font-size: 15px;
  color: #5f6368;
  line-height: 1.55;
}

ul {
  padding-left: 40px;
}

button {
  width: 200px;
  height: 42px;
  margin-top: 16px;
  background-color: #1989fa;
  border-radius: 6px;
  font-size: 15px;
  color: #fff;
  border: none;
  outline: none;
}

.webz {
  width: 100%;
  background-color: #2b4af5;
  height: 280px;
  position: relative;
}

.webz img {

  height: 176px;
  top: 60px;
  position: absolute;
  width: 422px;
  left: 22%;
}

.btn {
  border: 0px;
  left: 20%;
  position: relative;
  top: -140px;
  font-size: 26px;
  font-weight: 500;
  color: #FFFFFF;
  width: 170px;
  height: 55px;
  background: linear-gradient(180deg, #FFCE39 0%, #FD9301 100%);
  box-shadow: 0px 7px 11px 0px rgba(18, 36, 96, 0.19);
  border-radius: 30px;
}

.btn-bk {
  border: 0px;
  left: 22%;
  position: relative;
  top: -140px;
  font-weight: 500;
  color: #2E48F7;
  font-size: 26px;
  width: 170px;
  height: 55px;
  background: #FFFFFF;
  box-shadow: 0px 7px 11px 0px rgba(18, 36, 96, 0.19);
  border-radius: 30px
}

.page {
  width: 100vw;
  height: 100vh;
  display: none;
  justify-content: center;
  align-content: flex-start;
  flex-wrap: wrap;
}
.content{
  display: flex;
  justify-content: center;
  align-content: flex-start;
  flex-wrap: wrap;
}
.content img:nth-child(1) {
  margin-top: -40px;
}
.content img:nth-child(2) {
  width: 80%;
  height: auto;
 
}

功能概述

  • 此 CSS 文件为 HTML 页面提供样式,包括布局、字体、颜色、按钮样式等。

详细解释

  1. 全局样式:设置所有元素的内边距和外边距为 0,使用 box-sizing: border-box 盒模型。
  2. 网络连接错误页面样式(page_error:设置页面宽度和高度为视口大小,垂直居中显示内容。
  3. 结果显示区域样式(#result:设置外边距为 80px。
  4. 标题和文本样式:设置标题和文本的字体大小、颜色和行高。
  5. 按钮样式:设置按钮的宽度、高度、背景颜色、边框半径等样式。
  6. 网络连接成功页面样式(page:初始状态下隐藏页面,设置页面宽度和高度为视口大小,使用 flex 布局。

三、JavaScript 部分

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 定义一个可重置的一次性函数
 * @param {func} fn 要作用的函数
 * @returns {object} {runOnce:func, reset:func } 
 */
function resetableOnce(fn) {
    // 存储上次传入的函数
    let lastFn = null;
    // 存储函数执行结果
    let result = null;
    // 标记函数是否已经执行过
    let hasExecuted = false;

    function runOnce() {
        if (lastFn!== fn) {
            // 如果传入的函数和上次不同,重置状态
            lastFn = fn;
            hasExecuted = false;
        }
        if (!hasExecuted) {
            // 如果函数还未执行过,执行函数并保存结果
            result = fn.apply(this, arguments);
            hasExecuted = true;
        }
        return result;
    }

    function reset() {
        // 重置执行标记,让下一次调用 runOnce 时再次执行 fn 函数
        hasExecuted = false;
    }

    return { runOnce, reset };
}

// 以下代码为检测需要,请勿删除

try {
    module.exports = resetableOnce;
} catch (e) {}

功能概述

  • 定义了一个 resetableOnce 函数,用于包装另一个函数,确保该函数只执行一次,并且可以重置状态,让函数再次执行。

详细解释

  1. resetableOnce 函数
    • 接收一个函数 fn 作为参数。
    • 使用 lastFn 存储上次传入的函数,result 存储函数执行结果,hasExecuted 标记函数是否已经执行过。
    • runOnce 函数:如果传入的函数和上次不同,重置状态;如果函数还未执行过,执行函数并保存结果,将 hasExecuted 标记为 true;返回函数执行结果。
    • reset 函数:将 hasExecuted 标记重置为 false,让下一次调用 runOnce 时再次执行 fn 函数。
    • 返回一个包含 runOncereset 函数的对象。

四、工作流程▶️

  1. 页面加载
    • 浏览器加载 HTML 文件,解析其中的头部信息、样式和脚本。
    • 网络连接错误页面(page_error)显示,网络连接成功页面(page)隐藏。
  2. 点击重新连接按钮
    • 用户点击 “点击重新连接网络” 按钮,触发 clickEvent.runOnce 函数。
    • clickEvent 是使用 resetableOnce 函数包装的点击事件处理函数,确保点击事件只执行一次。
  3. 尝试重新连接网络
    • retry 函数开始尝试重新连接网络,最多尝试 5 次,每次尝试间隔 400 毫秒。
    • handleLink 函数模拟网络连接尝试,尝试 7 次以上认为连接成功。
    • 每次尝试时,按钮文本变为 “已经在尝试连接网络...”,并在结果显示区域显示尝试时间。
  4. 处理连接结果
    • 如果连接成功,retry 函数返回 “网络连接成功”,并在结果显示区域显示该信息。
    • 执行测试用例,验证 resetableOnce 函数的功能。
    • 如果测试通过,2 秒后隐藏网络连接错误页面,显示网络连接成功页面。
    • 如果连接失败,retry 函数抛出错误,按钮文本恢复为 “点击重新连接网络”,重置点击事件状态,并在结果显示区域显示错误信息。
  5. 重置状态
    • 如果需要再次尝试重新连接网络,可以调用 clickEvent.reset() 函数重置点击事件状态。

测试结果👍

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

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

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

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

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