原生JS之實現九宮格抽獎效果,今後百分之百中獎不是夢!!!

首先咱們來看一下效果: javascript

說明:在這個案例中,中止位置的輸入範圍是0-7,表明8箇中止位置(順時針排列),而後咱們後臺設置的中獎位置是1。html

8箇中止位置的分佈圖:java

0 1(中獎位置) 2
7 抽獎 3
6 5 4

下面是相關的代碼,相信聰明的你必定可以理解!數組

<div id="box">
    <div id="header">
      <span>中止位置:</span>
      <input type="text" value="0" id="txt">
    </div>
    <div id="comment"><span>輸入值的範圍:0-7,默認中止位置:0</span></div>
    <div id="main">
      <div class="num"><img src="./xingyun.jpg" alt=""></div>
      <div class="num"><img src="./xingyun.jpg" alt=""></div>
      <div class="num"><img src="./xingyun.jpg" alt=""></div>
      <div class="num"><img src="./xingyun.jpg" alt=""></div>
      <div class="num" id="mid"><input type="button" value="抽獎" id="start"></div>
      <div class="num"><img src="./xingyun.jpg" alt=""></div>
      <div class="num"><img src="./xingyun.jpg" alt=""></div>
      <div class="num"><img src="./xingyun.jpg" alt=""></div>
      <div class="num"><img src="./xingyun.jpg" alt=""></div>
    </div>
  </div>
複製代碼
* {
      margin: 0;
      padding: 0;
    }
 
    html,
    body {
      width: 100%;
      height: 100%;
    }
 
    #box {
      width: 100%;
      height: 100%;
      background-color: silver;
    }
 
    #header {
      width: 600px;
      height: 70px;
      margin: 0 auto;
      text-align: center;
      padding-top: 30px;
      background-color: aquamarine;
      opacity: 0.65;
    }
 
    #header span {
      line-height: 35px;
      font-size: 35px;
      color: black;
    }
 
    #header input {
      height: 40px;
      font-size: 35px;
    }
    #comment{
      width: 600px;
      height: 50px;
      margin: 0 auto;
      color: black;
      background-color: aquamarine;
      opacity: 0.65;
      text-align: center;
      font-size: 30px;
    }
 
    #main {
      width: 600px;
      height: 600px;
      margin: 0 auto;
    }
 
    .num {
      width: 200px;
      height: 200px;
      float: left;
      opacity: 0.3;
    }
 
    img {
      width: 100%;
      height: 100%;
    }
 
    #mid {
      opacity: 0.7;
    }
 
    #mid input {
      width: 100%;
      height: 100%;
      background-color: red;
      font-size: 40px;
      color: aliceblue;
      }
複製代碼
//定義一個定時器的句柄
    var interval = null;
    //定義點擊開始之後,定時器執行的時間間隔
    var inTime = 100;
    //獲取1-8的div
    var divNum = document.getElementsByClassName('num');
    //把獲取到的數組從新排序,由於獲得的divNum長度爲9,可是最中間的那個「開始」盒子不須要,並且divL裏面的class對象順序不符合要求
    var divList = [];
    for (let i = 0; i < 3; i++) {
      divList.push(divNum[i])
    }
    divList[3] = divNum[5];
    divList[4] = divNum[8];
    divList[5] = divNum[7];
    divList[6] = divNum[6]
    divList[7] = divNum[3];
 
    //自動轉圈函數
    function animation() {
      var index = 0;
      interval = setInterval(function () {
        //divList[index].style.opacity = 1;注意,這句不能寫在這裏,由於在最後,index會等於8,可是divList數組最大下標爲7
        if (index > 7) {
          index = 0;
          divList[7].style.opacity = 0.5;
        } else if (index != 0) {
          divList[index - 1].style.opacity = 0.5;
        }
        //給盒子的透明度設置爲1
        divList[index].style.opacity = 1;
        index++;
      }, 1000)
    }
    //頁面加載之後,先自動轉圈
    window.onload = animation;
 
    //爲盒子裏面的「開始」按鈕註冊點擊事件
    var inputStart = document.getElementById("start");
    var valTxt = document.getElementById("txt");
    inputStart.onclick = function () {
      //首先判斷用戶輸入的中止位置的值是否合乎格式,默認的位置爲0
      if (valTxt.value.length == 1 && parseInt(valTxt.value) >= 0 && parseInt(valTxt.value) <= 7) {
        //禁用按鈕
        inputStart.disabled="disabled";
        inputStart.value = "抽獎中..."
        //取消頁面加載之後設置的定時器(也就是取消自動轉圈)
        clearInterval(interval);
        //先更改全部的盒子透明度
        for (let i = 0; i < divList.length; i++) {
          divList[i].style.opacity = 0.5;
        }
        //設置更快的定時器,時間間隔爲inTime=0.1s
        var index = 0;
        interval = setInterval(function () {
          //divList[index].style.opacity = 1;注意,這句不能寫在這裏,由於在最後,index會等於8,可是divList數組最大下標爲7
          if (index > 7) {
            index = 0;
            divList[7].style.opacity = 0.5;
          } else if (index != 0) {
            divList[index - 1].style.opacity = 0.5;
          }
          //給盒子的透明度設置爲1
          divList[index].style.opacity = 1;
          index++;
        }, inTime)
        //快速轉圈兩秒之後,執行stop函數
        //思考一個問題?兩秒之後,快速轉圈還會繼續轉嗎?
        //答案:會的,兩秒後執行延時器裏面的操做之後,還會繼續執行定時器裏面的操做
        setTimeout(function () {
          stop(parseInt(valTxt.value));
        }, 2000)
 
      } else {
        alert("尊敬的用戶,請正確輸入中止位置的值!");
      }
      //讓轉動停下來,接收的形參爲中止位置的值
      function stop(luckPosition) {
        //清除定時器
        clearInterval(interval)
        //獲得opacity爲1的那個盒子的位置current
        var current = -1;
        for (let i = 0; i < divList.length; i++) {
          if (divList[i].style.opacity == 1) {
            current=i;
          }
        }
        //注意:current+1
        stopLuck(luckPosition,current+1,inTime,10)//inTime是點擊「開始」之後,定時器執行的時間間隔,大小爲100,也就是轉圈的速度
      }
      //
      function stopLuck(luckPosition,index,time,stepTime) {
        //設置一個延時器,0.1s之後執行(傳進來的time=100)
        //思考一個問題,爲何這裏也須要設置一個延時器,並且最開始時候,延遲時間time爲傳進來的inTime=100?答案在下面的註釋中!
        setTimeout(function () {
          //重置opacity
    //這裏須要注意兩個問題?
    //第一個問題:不明白爲何這裏須要重置opacity,由於在「開始」按鈕註冊點擊事件裏面的定時器函數語句會重置opacity,這裏再重置
        //是畫蛇添足,其實這裏重置opacity是爲了在遞歸該函數時候,重置opacity
    //第二個問題:第一次執行stopLuck函數的時候(也就是stop最開始調用stopLuck函數的時候),index的值實際上是
        //比opacity爲1的那個盒子下標大1,由於傳進來的是:current+1,因此認爲下面這種重置opacity的寫法會致使錯誤,可是重點來了!
        //這裏是設置了一個延時器,而且第一次的延遲時間爲time=inTime=0.1s,因此第一次執行stopLuck的時候,opacity爲1的那個盒子其實
        //已經繼續轉動一次,因此第一次執行stopLuck函數時候,下面這種寫法沒有錯
          if (index > 7) {
            index = 0;
            divList[7].style.opacity = 0.5;
            
          } else if (index != 0) {
            divList[index - 1].style.opacity = 0.5
          }
          // 當前位置選中狀態
          divList[index].style.opacity  = 1;
          // 若是說當前旋轉時間過短, 或者當前位置不等於中止位置, 遞歸一下,直到旋轉至中止位置
          //(注意:第一次的延遲時間爲time=inTime=0.1s)
          if (time < 400 || index != luckPosition) {
            //思考兩個問題?
            //第一個問題,若是index == luckPosition的話,會怎麼樣?
    //由於time < 400,仍然也會執行這裏,也就是說,即便當前位置等於中止位置也會執行這裏,爲了是使得速度先變慢。
    //而後index會再++直到time>=400而且index==luckPosition再也不執行這裏。
            //第二個問題,爲何愈來愈慢?
    //在最開始的時候,time=100,stepTime=10,index爲當前opacity爲1盒子的下標,因此執行到這裏,遞歸一下。time值和
    //stepTime值變大,那麼stopLuck()裏面的延時器的延遲時間也會變長,從而使得轉圈的速度變慢
    //同時index++,延時器裏面重置opacity的代碼會重置opacity,從而達到轉圈的效果
            stepTime++;
            time += stepTime;
            index++;
            stopLuck(luckPosition, index, time, stepTime);
          } else {
            //執行到這裏說明當前位置等於中止位置
            //設置一個延時器,爲了使1s後顯示結果
            setTimeout(function () {
    //這裏咱們後臺手動設置中獎的位置是:1,也就是輸入luckPosition的值爲1時中獎,固然也能夠設置中獎位置爲負數,從而永遠不中獎
              if (luckPosition == 1 ) {
                alert("恭喜中獎!")
                //恢復按鈕
                inputStart.disabled=false;
                inputStart.value = "抽獎";
                animation();
              } else {
                alert("很遺憾,你沒有中獎!")
                 //恢復按鈕
                inputStart.disabled=false;
                inputStart.value = "抽獎";
                animation();
              }
            },1000)
 
          }
        },time)
       }
      }

複製代碼
相關文章
相關標籤/搜索