Roulette lottery case implemented in native js

It has been two years since I came to the university. The place where I eat most is in the cafeteria. After such a long time, I have almost become tired of eating the food at every window, so I plan to make a roulette lottery to determine my choice. What to eat every day.

Table of contents

Realization renderings:

 Static construction

 js code

1. Ideas to implement this function:

 2. First obtain the DOM elements you need to use and define some variables that will be used.

3. Bind a click event to the button to trigger the roulette rotation

4. Implement functions

5. Let me briefly talk about the implementation ideas

 Complete code

Summarize


Realization renderings:

 Static construction

html structure

 <div class="box">
    <ul>
      <!-- 注意这里的类名是按照旋转速度来规范的 : item_index  为了方便我们后续再写js代码操作时更方便-->
      <li class="item_1">iphone14</li>
      <li class="item_2">冰箱</li>
      <li class="item_3">洗衣机</li>
      <li class="item_8">代金券</li>
      <li class="btn" style="background-color: #fff;">
        <button style="margin: 14px; width: 120px;height: 120px;background-color: pink;border: #fff;">点击抽奖</button>
      </li>
      <li class="item_4">电脑</li>
      <li class="item_7">电视</li>
      <li class="item_6">空调</li>
      <li class="item_5">特斯拉</li>
    </ul>
    <!-- 这里到时候放中奖信息的文字 -->
    <div class="text"></div>
  </div>

The class names I name here are for better operation when changing their class names later, so they are named in the order of the roulette rotation.

css

    * {
      margin: 0;
      padding: 0;
    }

    .box {
      width: 500px;
      height: 500px;
      margin: 100px auto;
    }

    ul {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
    }

    ul li {
      list-style: none;
      width: 150px;
      height: 150px;
      background-color: beige;
      margin: 5px;
      font-size: 25px;
      text-align: center;
      line-height: 150px;
    }

    ul li img {
      width: 100%;
      height: 100%;
    }

    .text {
      text-align: center;
      margin-top: 20px;
      font-size: 25px;
      color: red;
    }

    .active {
      background-color: rgb(93, 221, 157);
    }

The css also simply beautifies the page. Active is the color to be switched when rotating, and the others are some centered layouts, etc.

 js code

1. Ideas to implement this function:

The main thing is to write an execution function. The main function of this function is to add and delete the class name of the selected li element. It mainly uses a timer to implement this function.

 2. First obtain the DOM elements you need to use and define some variables that will be used.

const obj = {
      text: document.querySelector('.text'),
      btn: document.querySelector('.btn'),
    }
    const item = document.querySelectorAll('ul li')
    let rollTime; // 定义定时器变量用来清除定时器
    let time = 0; // 转动次数
    let speed = 10; // 转动时间间隔
    let times; // 总转动次数
    let sum = 0; //计算切换总次数

3. Bind a click event to the button to trigger the roulette rotation

  //按钮点击事件
    obj.btn.addEventListener('click', () => {
      obj.text.innerHTML = ''; //清空文字
      times = parseInt(Math.random() * (20 - 30 + 1) + 50, 10); // 定义总转动次数,随机40 - 60次
      console.log(times);
      time = 0  //每次点击需要将这几个数字进行初始化
      sum = 0
      spin()
    })

4. Implement functions

 function spin() {
      time++; // 转动次数加1
      sum++; //总转动次数加1
      //判断time是否大于8
      time = time > 8 ? 1 : time;
      //先清空其他的带有active类的li
      item.forEach(item => {
        item.classList.remove('active')
      })
      clearTimeout(rollTime);
      //给带有类名item_1的加上类名
      document.querySelector(`.item_${time}`).classList.add('active')
      rollTime = setTimeout(() => {
        window.requestAnimationFrame(spin); // 进行递归动画 这段代码的作用是启动一个动画帧,以便在浏览器中渲染动画效果。动画帧是通过调用requestAnimationFrame()方法实现的,它允许你在动画帧中执行代码,而不是直接设置元素的样式。这样可以确保在渲染过程中不会出现跳帧的情况,从而实现毫秒级的渲染效果。
      }, speed * sum)

      if (sum === times) {
        clearTimeout(rollTime); //清除定时器
        //找出带有active类名的文字
        const active = document.querySelector('.active').innerHTML
        obj.text.innerHTML = `恭喜你抽中了${active}`
        return
      }
    }

There are also some corresponding comments in the code

5. Let me briefly talk about the implementation ideas

There are a total of 8 items, so we need to judge the time flag. If it is greater than 8, it will change to 1, and then it will loop through to clear all active class names. The reason for clearing the previous timer here is because it is used in the timer. It’s time for recursive rendering, so you need to clear the previous timer, otherwise lags may occur. The last step is to make a judgment to exit the function and render the page. The function of window.requestAnimationFrame(spin) is listed in the code comments, mainly for rendering more information. It is smooth and does not suffer from lags. It is also ok to directly call recursion here.

 Complete code

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .box {
      width: 500px;
      height: 500px;
      margin: 100px auto;
    }

    ul {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
    }

    ul li {
      list-style: none;
      width: 150px;
      height: 150px;
      background-color: beige;
      margin: 5px;
      font-size: 25px;
      text-align: center;
      line-height: 150px;
    }

    ul li img {
      width: 100%;
      height: 100%;
    }

    .text {
      text-align: center;
      margin-top: 20px;
      font-size: 25px;
      color: red;
    }

    .active {
      background-color: rgb(93, 221, 157);
    }
  </style>
</head>

<body>
  <div class="box">
    <ul>
      <!-- 注意这里的类名是按照旋转速度来规范的 : item_index  为了方便我们后续再写js代码操作时更方便-->
      <li class="item_1">iphone14</li>
      <li class="item_2">冰箱</li>
      <li class="item_3">洗衣机</li>
      <li class="item_8">代金券</li>
      <li class="btn" style="background-color: #fff;">
        <button style="margin: 14px; width: 120px;height: 120px;background-color: pink;border: #fff;">点击抽奖</button>
      </li>
      <li class="item_4">电脑</li>
      <li class="item_7">电视</li>
      <li class="item_6">空调</li>
      <li class="item_5">特斯拉</li>
    </ul>
    <!-- 这里到时候放中奖信息的文字 -->
    <div class="text"></div>
  </div>
  <script>
    //简易的抽奖功能
    const obj = {
      text: document.querySelector('.text'),
      btn: document.querySelector('.btn'),
    }
    const item = document.querySelectorAll('ul li')
    let rollTime; // 定义定时器变量用来清除定时器
    let time = 0; // 转动次数
    let speed = 10; // 转动时间间隔
    let times; // 总转动次数
    let sum = 0; //计算切换总次数
    //按钮点击事件
    obj.btn.addEventListener('click', () => {
      obj.text.innerHTML = ''; //清空文字
      times = parseInt(Math.random() * (20 - 30 + 1) + 50, 10); // 定义总转动次数,随机20-30次
      console.log(times);
      time = 0
      sum = 0
      spin()
    })
    //写一个函数用来模拟轮盘抽奖,旋转次数也是模拟的

    function spin() {
      time++; // 转动次数加1
      sum++; //总转动次数加1
      //判断time是否大于8
      time = time > 8 ? 1 : time;
      //先清空其他的带有active类的li
      item.forEach(item => {
        item.classList.remove('active')
      })
      clearTimeout(rollTime);
      //给带有类名item_1的加上类名
      document.querySelector(`.item_${time}`).classList.add('active')
      rollTime = setTimeout(() => {
        window.requestAnimationFrame(spin); // 进行递归动画 这段代码的作用是启动一个动画帧,以便在浏览器中渲染动画效果。动画帧是通过调用requestAnimationFrame()方法实现的,它允许你在动画帧中执行代码,而不是直接设置元素的样式。这样可以确保在渲染过程中不会出现跳帧的情况,从而实现毫秒级的渲染效果。
      }, speed * sum)

      if (sum === times) {
        clearTimeout(rollTime); //清除定时器
        //找出带有active类名的文字
        const active = document.querySelector('.active').innerHTML
        obj.text.innerHTML = `恭喜你抽中了${active}`
        return
      }
    }

  </script>
</body>

</html>

Summarize

If you are like me and don’t know what to eat every day, you can try using this roulette to decide.

Eat well, study well, and have a happy day

Guess you like

Origin blog.csdn.net/m0_64642443/article/details/132794708