JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)

yizhihongxing

我将详细讲解“JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)”,并给出两个示例说明。

JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)

前言

上一篇文章已经介绍了JavaScript实现跑马灯抽奖活动的基本思路和代码,在这篇文章中,我们将分析、优化并完善之前的代码。接下来我们将介绍具体的步骤。

代码优化

1. 变量申明

原来的代码中,所有的变量都是使用var声明的。但是var是在函数中申明变量的,会存在变量提升的问题。所以优化的第一步是使用let和const来代替var,确保变量只在需要使用的代码块内部定义。

2. 代码简化

原来的代码在每次转动时都需要重新计算距离,这样会增加代码的复杂度和运行时间。我们可以将转动距离提前进行预处理,避免重复计算。

同时,我们可以将一些重复代码进行封装,使代码更加简洁易读。

3. 细节优化

在实际使用中,用户可能会连续多次点击开始按钮,这样会导致每个跑马灯都在不停地旋转,造成资源浪费。我们可以添加一些判断措施,确保每次只有一个跑马灯在旋转。

完整代码

下面是优化后的完整代码:

const lottery = document.querySelector(".lottery");
const startBtn = document.querySelector(".start-btn");

startBtn.addEventListener("click", () => {
  if (lottery.classList.contains("active")) return; // 判断是否已经在旋转

  const prizes = ["电视", "手机", "平板电脑", "电饭煲"];
  const prizeIndex = Math.floor(Math.random() * prizes.length);
  const prize = prizes[prizeIndex];

  lottery.classList.add("active");

  let rotateCount = 0;
  const rotateUnit = 45; // 每次旋转的角度
  const rotateNum = 8; // 旋转次数
  const totalAngle = rotateNum * 360 + prizeIndex * rotateUnit; // 总的旋转角度

  for (let i = 0; i < 4; i++) {
    const list = lottery.querySelector(`.list-${i}`);
    list.style.transform = `rotate(${totalAngle}deg)`;
  }

  setTimeout(() => {
    lottery.classList.remove("active");
    alert(`恭喜你获得了${prize}`);
  }, 4000);
});

示例说明

示例一

在原来的代码中,每次旋转时都需要重新计算距离。下面是优化前的代码:

const rotate = (index, deg, speed, timer) => {
  const lottery = document.querySelector(".lottery");
  const lists = lottery.querySelectorAll(".list");
  const distance = index * avgDeg - deg; // 计算距离
  let speedMod = speed;

  clearInterval(timer);

  timer = setInterval(() => {
    if (speedMod > 0 && distance < 0) {
      // 是否需要旋转到下一个转盘
      distance += 360;
    } else if (speedMod < 0 && distance > 0) {
      // 是否需要旋转到上一个转盘
      distance -= 360;
    }
    deg += speedMod;

    if (Math.abs(distance - speedMod) < Math.abs(speedMod)) {
      // 最后一步旋转到奖品
      deg += distance;
      clearInterval(timer);
    }

    distance -= speedMod;
    speedMod *= 0.98; // 加速度递减
    speedMod = speedMod < 0.1 ? 0.1 : speedMod; // 最小速度为0.1

    lists.forEach((list, i) => {
      const itemDeg = avgDeg * i;
      list.style.transform = `rotate(${deg + itemDeg}deg)`;
    });
  }, 10);

  return timer;
};

可以看到,每次计算距离的代码比较麻烦。我们可以在代码中预处理需要旋转的角度,避免重复计算。下面是优化后的代码:

const rotate = (index, deg, speed, timer) => {
  const lottery = document.querySelector(".lottery");
  const lists = lottery.querySelectorAll(".list");
  let speedMod = speed;

  clearInterval(timer);

  timer = setInterval(() => {
    deg += speedMod;
    rotateCount++;

    if (rotateCount >= rotateNum && (deg - totalAngle) % 360 == 0) {
      clearInterval(timer);
      rotateCount = 0;
      lottery.classList.remove("active");
      alert(`恭喜你获得了${prize}`);
      return;
    }

    speedMod *= 0.98;
    speedMod = speedMod < 0.1 ? 0.1 : speedMod;

    lists.forEach((list, i) => {
      const itemDeg = i * rotateUnit;
      list.style.transform = `rotate(${deg + itemDeg}deg)`;
    });
  }, 10);

  return timer;
};

示例二

在实际使用中,用户可能会连续多次点击开始按钮,这样会导致每个跑马灯都在不停地旋转,造成资源浪费。我们可以添加一些判断措施,确保每次只有一个跑马灯在旋转。下面是添加判断措施后的代码:

const lottery = document.querySelector(".lottery");
const startBtn = document.querySelector(".start-btn");
let isRunning = false; // 判断是否正在旋转

startBtn.addEventListener("click", () => {
  if (isRunning) return; // 判断是否已经在旋转

  isRunning = true;

  const prizes = ["电视", "手机", "平板电脑", "电饭煲"];
  const prizeIndex = Math.floor(Math.random() * prizes.length);
  const prize = prizes[prizeIndex];

  lottery.classList.add("active");

  let rotateCount = 0;
  const rotateUnit = 45; // 每次旋转的角度
  const rotateNum = 8; // 旋转次数
  const totalAngle = rotateNum * 360 + prizeIndex * rotateUnit; // 总的旋转角度

  for (let i = 0; i < 4; i++) {
    const list = lottery.querySelector(`.list-${i}`);
    list.style.transform = `rotate(${totalAngle}deg)`;
  }

  setTimeout(() => {
    isRunning = false;
    lottery.classList.remove("active");
    alert(`恭喜你获得了${prize}`);
  }, 4000);
});

在上面的代码中,我们添加了一个isRunning变量来判断是否正在旋转,如果已经在旋转了,就不执行后续操作。这样就可以避免资源浪费了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript实现跑马灯抽奖活动实例代码解析与优化(二) - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • JavaScript中利用构造器函数模拟类的方法

    构造器函数是JavaScript中一种特殊的函数,用于创建和初始化对象。利用构造器函数可以模拟类的概念。本文将介绍如何使用构造器函数来实现类似于类的功能。 创建构造器函数 要创建一个构造器函数,可以使用function关键字,并使用大写字母开头的函数名。下面是一个示例: function Person(name, age) { this.name = nam…

    JavaScript 2023年6月10日
    00
  • js前端面试之同步与异步问题详解

    JS前端面试之同步与异步问题详解攻略 1. 同步与异步的概念 同步和异步都是指程序的执行方式,它们的区别在于程序执行完成的时间点不同。同步是指代码按照顺序一行一行地执行,需要等待前面的代码执行完成后才会执行后面的代码。而异步则是指代码不需要按照顺序执行,可以在后台继续执行其他代码,当前面的代码执行完成后再回来执行后面的代码。 2. 同步与异步的应用场景 同步…

    JavaScript 2023年5月28日
    00
  • Javascript Global encodeURI() 函数

    以下是关于JavaScript Global对象中encodeURI()函数的完整攻略,包括两个示例说明。 JavaScript Global对象中的encodeURI()函数 JavaScript Global对象中的encodeURI()函数用于将一个URI字符串进行编码以便在URI中使用。URI(Uniform Resource Identifier)…

    JavaScript 2023年5月11日
    00
  • 浅析JavaScript中的Proxy对象

    浅析JavaScript中的Proxy对象 什么是Proxy对象 Proxy是ES6中新增的一个特性,用于拦截并可自定义处理对象的各种读写操作。Proxy是一个代理对象,它包装了原始对象,对原始对象进行拦截,从而使得原始对象的行为可以由代理对象来控制和修改。 Proxy对象的作用 Proxy对象主要有以下两个作用: 拦截并处理对象的读取和赋值操作:通过Pro…

    JavaScript 2023年6月10日
    00
  • JS基于FileSaver.js插件实现文件保存功能示例 原创

    c1 简介 本文介绍了如何使用FileSaver.js插件实现Javascript文件保存功能。 FileSaver.js是一个Javascript库,提供了将文件保存到本地的功能。该库主要用于浏览器端,支持多种类型的文件格式,包括文本、CSV、PDF、Image等等。 c2 安装 要使用FileSaver.js插件,需要先将其引入到HTML页面中。可以通过…

    JavaScript 2023年5月27日
    00
  • js将列表组装成树结构的两种实现方式分享

    让我们来详细讲解“js将列表组装成树结构的两种实现方式分享”的完整攻略。 1. 背景 在开发网站时,经常会遇到需要将列表数据组装成树形结构的需求。比如,某个商品分类下有多个子分类,子分类又有自己的子分类,这就是一棵树形结构。如果我们只有一份列表数据,该如何将它组装成一棵树呢? 2. 实现方式一:递归 2.1 实现思路 递归是一种非常自然且直观的方法,它通过不…

    JavaScript 2023年5月27日
    00
  • javascript 定时器工作原理分析

    JavaScript 定时器工作原理分析 一、概述 JavaScript 定时器是指可以在代码执行期间设定一个定时任务,在经过一段时间后执行任务的功能。常见的定时器包括 setTimeout 和 setInterval。通过定时器,我们可以实现一些周期性的或者延迟执行的逻辑。 二、setTimeout setTimeout 是 JavaScript 中最常用…

    JavaScript 2023年6月11日
    00
  • js中判断Object、Array、Function等引用类型对象是否相等

    JavaScript 中判断对象是否相等比较复杂,因为对象具有引用类型的特性,即两个变量即使引用同一个对象,它们也不一定相等。 以下是一些常见的判断方法和示例: 1. 使用 Object.is() 方法 Object.is() 方法可以判断两个对象是否相等,与 === 操作符相似。它的返回值为一个布尔值。 以下是示例代码: const obj1 = { a:…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部