用原生 JavaScript 做一個簡單的抽獎功能頁面

用原生JS做一個簡單的抽獎功能頁面
用原生JS做一個簡單的抽獎功能頁面

本篇會完成的 Demo

用原生 JS 做一個簡單的抽獎功能頁面 Demo

這個是 2 年前製作的功能了,那時看見很多活動頁上都在玩抽獎,就自己動手寫了一個出來。

但只拿來玩抽獎覺得平常不太會用到,就把名稱改成「午餐吃什麼」,把抽獎的名單換成店家名稱,順便再加上 Google Maps 進去,就解決不知道午餐要吃什麼的煩惱啦~

2022.06.20 更新:Demo 及原始碼修正了小錯誤,也把調用 Google Sheets API 的部份調成 V4 版的。


本篇用到資源

原本 JS 的部份是用 jQuery 寫,這幾天改成原生的 JS,用 ES6,如果看完這篇想下載來用時,請再編譯成 ES5 才支援 IE(在此宣傳請放棄 IE 這隻上古神獸)。

店家名單的部份,為了方便管理,是寫在 Google Sheets 上,如何把 Google Sheets 當資料庫用可參考這篇:如何用 Google Sheets / Excel 當作資料庫

頁面上的 CSS 是自己手刻,icon 的部份用 FontAwesome 4.7


HTML 部份

HTML 的部份,分為顯示名單、按鈕、地圖,這三個大區塊,都用 HTML5 的語意化標籤 section 包起來。

按鈕分二個,分別是切換素 / 葷食,以及啟動抽獎。

切換素 / 葷食改在抽獎的話,可以是「會員 / 非會員」、「有資料 / 無資料」等選項,就在撈名單的步驟分成兩個陣列來存就行。

參考原始碼如下:

看 HTML 可以發現,切換素 / 葷食的按鈕,實際上是 checkbox,樣式全做在 labelspan 上,input 本身不寫樣式,只寫 checked 時相鄰的 span 變化。

start 按鈕,加入了四個 span,這主要是做按鈕四個邊的動畫效果。

iframe 的 Google Map 先不寫 src 的值,這會用 JS 去抓抽獎結果的文字塞。


CSS 部份

CSS 部份唯一要說明的,就是按下 start 後,會跑的拉霸動畫。

拉霸動畫不難,就是讓每一個選項的 top 從 0%-100% 時一直往上移,名單愈多的,它的 top 就愈大,執行動畫秒數就愈多。

一般來說,可以用 JS 去計算抽獎名單的數目,然後每一多個名單,topanimation-duration 就相對遞增。

但,Sass 本身也有 for 迴圈 可以使用。之前看過一句話,就是能用 CSS 解決的事,就不用 JS 去解決,因為 JS 比較耗資源。(不要問是哪裡看到的,我也忘了)

Sass 的迴圈可以拿來做計算,本功能寫的如下:

@for $i from 1 through 50
  $t: .03s * $i
  @keyframes spin-#{$i}
    from
      top: 0
    to
      top: calc(-73px * #{$i})
  .god .wrap > .span-#{$i}
    animation-name: spin-#{$i}
    animation-duration: $t

預設先寫了 5 0個名單內的 animation,如果名單有超過再改數字重新編譯就行。

補充說明一個效果,就是 start 按鈕四個邊線的效果。

其實就是讓四個邊的 delay 時間不一樣,transition-origin 的起點也不一樣就行。


JS 部份

JS 部份看原始碼就可以看到,說明的註解也都寫了上去。

要說明的就是,其實在按下 start 按鈕後,中獎名單就已經出來了,拉霸在那邊跑是掩人耳目用,最後再用 setTimeout 去移掉拉霸效果跟放 Google Map Iframe 的 src

中獎名單用一個簡單的取亂數 function 就行:

r = () => {
  max = toggle.length - 1;
  min = 0;
  return Math.floor(Math.random() * (max - min + 1)) + min;
};

取亂數的最大值,就是抽獎名單的總數 -1,因為陣列是從 0 開始算,所以要 -1。

Google Map 的部份是用 Google Maps Embed API,選用基本的 Place Mode,是免費的,才不會說玩到一半還要收錢,Embed API 用的 src url 如下:

https://www.google.com/maps/embed/v1/place
  ?key=YOUR_API_KEY
  &q=店家名稱

YOUR_API_KEY 要從 Google Cloud Platform 去建立專案後取得。店家名稱直接複製 Google Map 的店家名稱即可。

相關文章:Google Maps API 學習筆記 – 1:地圖、標記、客製樣式

抽獎名單資料庫

抽獎名單的資料庫,選用的是 Google Sheets,之所以會選擇 Excel 而不是 Firebase,主要是製作時想讓非工程師的人員來維護,而又懶得再花時間製作一個後台介面,就選了大家普遍會用的 Excel。

在 Google Sheet 上的資料可以直接看這,就是從這邊撈取抽獎名單的:


範例頁面、原始碼

本篇完成的範例頁面在這,大家可以玩玩看,直接查看頁面原始碼可以看到HTML、JavaScript:

https://letswritetw.github.io/letswrite-food-check/

原始碼也放上 Github 了,可以直接下載使用:

https://github.com/letswritetw/food-check

Summary
用原生 JavaScript 做一個簡單的抽獎功能頁面
Article Name
用原生 JavaScript 做一個簡單的抽獎功能頁面
Description
本篇大綱:本篇會完成的Demo、本篇用到資源、html部份、css部份、js部份、抽獎名單資料庫、範例頁面、原始碼。很多活動頁上都在玩抽獎,就自己動手寫了一個出來。把抽獎的名單換成店家名稱,順便再加上Google Map進去,就解決不知道午餐要吃什麼的煩惱啦~
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg
訂閱
通知
guest

4 Comments
最舊
最新
Inline Feedbacks
看所有留言
Michael
Michael
3 年 之前

前陣子搞了一個類似的抽午餐系統
是用 Excel 做的,只能自己離線玩玩…
剛好最近想升級成網頁版,分享給更多人
就像您這樣的網頁,超符合我的需求XD
只是我是完全新手…
(連用什麼 “程式” 去運行 “html, ccs, js” 部分都還不了解XD)

還在努力中!
感謝您分享,相信我應該會成功
(已請咖啡表示謝意 :D)

Ryan
Ryan
3 年 之前

不好意思覺得很厲害,但是想請問如果想要在結果出來前,在某一個選項停留久一點之後再顯示最後抽籤結果,有一點像大部分抽獎遊戲那樣,以為抽中了,結果又偷轉這樣,請問該如何修改呢? 謝謝

ans9323052
ans9323052
2 年 之前

感謝大大的文章。我想請問一下,抽中後再同步回去google sheet 的欄位註記,該怎麼寫呢?

有找到方法: spreadsheets.values.update 但有看沒有懂,官方的範例是使用sheet API 套件來完成。不知道有沒有只用j s 丟到google sheet可以寫入值的方式。 先留言,再來繼續找方法。

感謝。