[Hero Of UnderGround 地下城] — 10F Chrome extension 幹話生產器

zip檔下載 & 程式碼

Zip : 點我

Code Source:點我

Introduction & 前言

距離上次更新已經一段時間了,慚愧。這段時間其實一直卡在九樓,還有工作、偷學Webpack……等等東忙西忙,眼看時光流逝,覺得不能再拖,就直接上十樓打雙數的第一位 Boss 了。還好前面都還有勇者擋著,目前計畫這關打完,再回去繼續把九樓完成,請原諒我…(逃

10F — 第一位雙數大魔王

Summary & 摘要

由於JS地下城每個BOSS的弱點都不一樣,每一層都要由弱點去進行攻略,本次BOSS的弱點有六項。

  1. 【特定技術】請開發 Chrome extension,不需上架,投稿時請提供安裝檔放在雲端,以供 GM 下載測試。什麼?你說你想上架?嘛.. 人生想要什麼都嘗試,也是可以的啦。

  2. 【特定技術】打開 Chrome 新頁(tab)時,會隨機顯示你自己新增的語錄,或者是幹話。

  3. 【特定技術】可切換夜間/日間模式。

4.【特定技術】新增語錄時,有兩種方式新增,一種是在頁面裡新增,另一種是點選瀏覽器右上角 icon 來新增。

5.【特定技術】背景插圖固定即可,目前的圖片只提供兩張,設計師本來很殘忍地說:「要不要也讓語錄也能新增客製化背景圖片?」,校長想了想,還是決定固定就好,不要太殘忍,當然你想試試看,校長也是不反對啦。

6.【書寫能力】請寫一篇 BLOG 來介紹你的挑戰過程,目前 Chrome 插件的教學文尚嫌太少,曾經鐵人邦有寫過一系列教學文,但仍尚缺整個上架流程的文章,為了豐富網路上的各種攻略資源,這個重責大任就交給地下城的各位勇者們了!(拍肩

好久沒有寫文章覺得都生疏了,不過本來初衷就是寫給自己複習的,應該也沒人會看啦,苦笑。


Chrome Store

什麼是 Chrome Extension ?

*簡單來說就是屬於一種 外掛,可以想成是輔助程式。目前可以分成三大類,應用程式 (Chrome Apps)、擴充功能 (Chrome Extensions)、主題 (Chrome Themes)…等*

我想第一次接觸的工程師通常比較關心的是,我該如何做出一個 Chrome Extension 呢?首先必須要會基本的 HTML CSS Javascript 這三項,除非你想做的是主題,這邊就先不討論這塊。

打底很重要!

任何東西都有一定的規則在,*Chrome Extension 也不例外,它本身有自己的架構在。(拜讀了前人大神文章後從 Chris Chuang 大神那兒得知 大兜 大神的文章 有興趣可自行拜讀)*

其實簡單的一隻 manifest.json 也能完成

manifest.json:這是 Chrome Extension 的心臟,支撐整個架構的檔案,用來描述檔案內容及資源,好比 package.json
Background Pages:這是常駐的在背景的檔案,比如裡面可以寫 javascript 用來監聽你的頁面內容,也可以是 HTML
UI Pages:用來使用者互動的頁面,或是你可以新增好幾個分頁,比如後面會用到的 newtab.html


我該怎麼著手?

由於這次也是第一次玩 Chrome Extension ,就照起手式先從 manifest.json 開始吧

來一張完整的結構圖 下方提供複製

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"manifest_version": 2,
"name": "幹話產生器",
"description": "[Hero Of UnderGround 地下城] — 10F Chrome extension(幹話生產器)",
"version": "1.0",
"author": "RexHung",
"icons": {
"16": "assets/icons/icon-16px.png",
"64": "assets/icons/icon-64px.png"
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"64": "assets/icons/icon-64px.png",
"128": "assets/icons/icon-128px.png"
}
},
"chrome_url_overrides": { "newtab": "./newtab.html" },
"permissions": [
"activeTab",
"storage"
],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
}

首先 manifest_version 代表 manifest file 格式版本的整數,如果使用的是 Chrome 18 以上,則應該設定成 2。接下來後面則是名字描述版號作者圖標…等等。

版號切記!最多由四個整數組成,並且用逗號(.)分開,數字必須介在 0 到 65535 之間,而且不可以 0 當開頭。

隨後的 browser actions 可以在 chrome 上方工具條的右側增加一个圖標,並且點下後出現的頁面 “default_popup”: “popup.html” 就是這個了。後面的 default_icon 即是工具欄出現的 icon 及顯示在擴充工具裡的圖案。( 這邊的 browser actions 也可以使用 Page Action 差別在於前者是任何分頁下都可以點選工具欄上的 icon 後者是在特定頁面才能點選)

**browser actions 定義的頁面**

在下面的 “chrome_url_overrides”: { “newtab”: “./newtab.html” } 就是當使用者點選分頁的時候會出現的頁面。

permissions 則是聲明權限,這個很重要,由於我們這次想做到兩個頁面同步的效果( 下拉的語錄和分頁的語錄算是兩個獨立頁面 ),只靠本地的 localStorage 是很麻煩的。幸好 Google 提供了 chrome.storageAPI ,它提供了 chrome.storage.sync、chrome.storage.local、chrome.storage.managed… 三種類型讓你儲存資料,有興趣可以點我拜讀文章。重點是在 manifest.json 內必須聲明。

最後一個是 内容安全策略標頭,這邊先不討論這個。


HTML 的部分?

1
<script *src*="./assets/js/cover.js"></script>

記得有多少檔案想共用 chrome.storage 就要都引入同一隻 JS 喔!


我該怎麼使用?

很簡單,把你的整包檔案拉到 chrome://extensions/ 內,他就會自己跑,如果有錯誤,也會提示,剛開始我也在 icon 上卡了好一下子呢!

你的第一個外掛出現啦

Code到用時方恨少!

剛開始覺得不就一個類似 Todo-list 的東西嗎?後來實作後才發現有點兒麻煩,主要是我先切了一個頁面弄好功能後才去考慮到另一個頁面的同步問題,再次檢討自己,以後做事情前要先確認過啊,不然就會重複做好幾次工。

基本上下拉的頁面跟分頁頁面切版不是主要難度,不過在分頁排版上這次算是第一次使用 transform: translateX(0%) 去弄成彈跳窗。

自從 css 加上 *transition 整個流暢多不會死板板*

關於大魔王同步

還記得這次的挑戰做了兩天,前一天在切版的時候很開心弄一頁,同步也盤算好了,東西都塞到 localStorage 內了,結果發現到另外一頁會搞得很麻煩。結果算是又小翻修了一次 Code,那時候才發現 Google 有提供 StorageApi。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let SwitchBtn = document.querySelector('#myonoffswitch'); // 滑動鈕

chrome.storage.sync.get(null, data => {

// 一開始會去讀你的 storage 內的資料

SwitchBtn.addEventListener('click', () => {

// 做什麼事情...

});

chrome.storage.onChanged.addListener(changes => {

// 當 chrome.storage 有變動的時候 就做什麼事情

});

});;

苦惱了一下的問題其實全部靠著個就能迎刃而解,很簡單的,分成三部分。

第一部分 chrome.storage 會去抓你的資料,我們放到最後處理。

第二部分 addEventListener 用來判斷使用者點了什麼或是做了什麼你指定的地方然後你要它發生什麼預期內的事情,比方點了開關的 Button 後你要讓 storage 塞進一個 key : value 或是讓 Button 變色、或是跑其他 function 都可以。

第三部分 addListener 用來監聽如果 chrome.storage 發生改變,就做什麼事情。這邊就要提到最常用的,chrome.storage.sync.set({ key : value}) 了。

我的做法是在第二部分塞入 chrome.storage.sync.set({ key : value}) 後,只要陣列有更動,我就把要做的事情放到第三部分,這樣兩邊都會同步一起做事情。


舉個例子吧

就拿 開關燈 來做例子,首先先宣告,並且給 value 一個值。

1
2
let SwitchBtn = document.querySelector('#myonoffswitch'); // 開關鈕
let value = 1; // key的value

第二步驟

然後第二步加入事件,當我點下開關鈕就塞入一個 Valuechrome.storage,隨後判斷那個 Value 是多少。我的設定 1 是白色,0 是黑色,裡面加入判斷,並且更換陣列的值,引發第三步的監聽事件發生。

第三步驟

第三步驟也很簡單,直接寫上你想要改變的事情,在這裏兩邊的 HTML 都吃得到,不過要記得,兩邊都要引入同一隻 JS 檔案。

這大概是這關最難的點

依樣畫葫蘆

1
if (changes.hasOwnProperty('key')) {});

後面第三步驟加上這個,把 key 改成想監聽的事件,就基本上都完成啦!

大功告成啦


我該怎麼大賣我的作品?

關於上架的部分,可以參考這篇文章。另外很重要的一點要提醒,要是你是第一次上架 chrome extension 的商品,必須收取 五塊美金 的費用,沒錯!就是 五塊美金,或許是多一道機制,讓大家不會胡亂上傳吧。

如果下次你又突然想上傳 Android app 或是 Chromecastapp 都是要在另外付一次的喔。


Conclusion & 結論

部落格停擺了一個月了,這段時間一直卡在九樓,加上忙東忙西的,其實是自己小怠惰了🤫。這段時間也從研究 pug 摸到了 Webpack,有機會再說說,也摸了好一下子 canvas,不過我想最主要還是要把 JS 練好,眼看樓層越來越高,離的越來越遠,就要告訴自己不能怠惰了,雖然現在還都是超級菜鳥一枚,還是要抱著不怕摔的心情努力勇往向上。期許多年後的自己看到現在能感謝現在的自己。

這次一開始其實沒有想到有這麼多地方可以用 Vue 簡單解決,所以就直接開了檔案直接硬幹了,沒想到又錯失一次練習機會,沒關係,我們11樓再見,最後除了繼續努力之外還是要列出檢討的地方,然後朝下一關繼續加油,完畢。(哎不對欸,九樓還沒好啊,誤

  • JS

  • Vue

  • 邏輯

  • 文筆

  • 體重

(慘了越來越多…


我的其他範例

  • Hero Of UnderGround — 1F Multiplicatio 九九乘法表

    Demo:點我

    Code Source:點我

  • Hero Of UnderGround — 2F Clock 時鐘

    Demo:點我

    Code Source:點我

  • Hero Of UnderGround — 3F Calculator 計算機

    Demo:點我

    Code Source:點我

  • Hero Of UnderGround — 4F World Clock 各國時區

    Demo:點我

    Code Source:點我

    Blog:點我

  • Hero Of UnderGround — 5F AQI 全台空氣指標儀表板

    Demo:*點我

    Code Source:*點我

    Blog:點我

  • Hero Of UnderGround — 6F SECONDS CHALLENGE 倒數遊戲

    Demo:點我

    Code Source:點我

    Blog:點我

  • Hero Of UnderGround — 7F Canvas 畫板

    Demo:點我

    Code Source:點我

    Blog:點我

  • Hero Of UnderGround — 8F Tic-Tac-Toe 井字遊戲

    Demo:點我

    Code Source:點我

    Blog:點我

Vue系列 —

  • [Vue Notes] — Vue-Cli #1 初次見面

    Blog:點我


參考網站