谷歌拓展程序初體驗

谷歌的拓展其實就是一(幾)個網頁而已拉, 1分鐘就能夠很容易弄起來一個谷歌拓展. 因此gogogo.前端

簡單的介紹

什麼是chrome拓展

因此chrome拓展乃谷歌chrome提供的可在瀏覽器上作一些小程序的功能. 編寫的方式就是普通的前端網頁技術. 功能不少不少. 這篇文章也只是講不多一部分. 可能一些別的瀏覽器也支持chrome拓展, 我並無仔細看.vue

如何加載/打包拓展程序

在瀏覽器地址欄輸入chrome://extensions/就能夠看到拓展啦. 這裏簡單說一下4個按鈕:git

  • 右上角Developer mode勾選之後進入了開發者模式
  • 下方Get more extensions能夠進入商店選擇別人寫的拓展
  • 正中的位置左邊的按鈕Load unpacked extension是開發的時候加載的按鈕
  • 正中的位置右邊的按鈕Pack extension做用是打包完成的拓展.

而後的話若是能夠把本身開發的拓展註冊在谷歌上. 也不貴.github

一個能夠運行的拓展程序的組成部分

只要Load unpacked extension成功就能夠算一個拓展了. 一個拓展須要:web

  • 一個文件夾, 加載的時候就加載他.
  • 一個manifest.json文件.

好了. chrome

那麼manifest.json的內容呢, 以下:json

{
    "name": "myExt",
    "version": "extVersion",
    "manifest_version": 2
}

沒錯, 只須要3個字段拓展就ok了. manifest_version必定是數字2. 其餘的爲字符串, 內容隨意.小程序

經常使用內容介紹

chrome拓展的文檔在這, manifest的字段不少, api更多. 這個章節講一些經常使用的api和插件運行方式.後端

manifest

  • description: 項目描述
  • icons: 顯示在拓展界面的圖表
  • browser_action: 拓展對瀏覽器的影響. (好比小圖標的顯示, 右擊菜單等)
  • content_scripts: 對訪問的頁面進行操做的腳本.
  • background: 後臺, 這個後面會講
  • options_page: 選項卡的頁面, 右擊拓展圖表會有選項的選項. 點擊會進入這個配置的頁面.
  • perissions: 需求的權限. 你的拓展能夠調用的api的權限在這分配. 固然也回在用戶加載你的拓展的時候被提示. 這是一些影響很大的權限. 好比操做storage(隨用戶名漫遊的), 桌面提醒(與web的api是不一樣的), 操做書籤(這個真的厲害了, 能夠清空你全部書籤), 右擊菜單(這個也很帥)等.

後臺

咱們的拓展在browser_action中能夠指定default_popup字段來指定一個點擊圖表後彈出的頁面, 其實也就是拓展的主界面(也有不少拓展沒有彈出頁面). 這個頁面用於展現, 關閉當前頁面或者關閉彈出也就會關閉這個頁面, 因此沒法進行數據的保存.api

那麼數據的保存就有background指定的文件來作. 打開瀏覽器後background就會在後臺運行. 而且他是有頁面的(通常不指定, 由於大多狀況沒有意義). 在這裏能夠保存數據, 操做api.

也就是說後臺相似於服務端, 彈出頁面相似於前端. 他們的交互由api實現. 而且交互的api有個比較坑的地方, 接口須要即便相應, 只要有等待的操做會當即返回undefined, 具體原理或者是否可配置尚未深刻.

API

好拉稍微介紹幾個api. 這些api一般在background中調用的, 緣由在上節說了, 少部分在彈出頁面調用.

消息傳遞

這個api很重要, 等因而前端後端的協議了. 用起來很簡單, 可是以爲坑也是有的, 在上節已經提到一個了. 而後他沒有相似'事件名字'意思的字段, 就直接發個數據, 另外每次傳遞數據會帶着當前tab的信息的. 我就爲這個消息作了最簡單的封裝:

class sender {
    send(event, data = null) {
        return new Promise((resolve) => {
            chrome.runtime.sendMessage({request: event, data: data}, function (response) {
                resolve(response);
            });
        });
    }
}
class reciever {
    constructor() {
        this.events = {};
        chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
            message.request && this.events[message.request] && sendResponse(this.events[message.request](message.data));
        });
    }

    on(event, fn) {
        this.events[event] = fn;
        return this;
    }
}
export let Message = {
    get sender() {
        return new sender();
    },
    get reciever() {
        return new reciever();
    }
};

桌面提示

這個桌面提示與h5接口略有不一樣, 能夠改變, 能夠銷燬, 彈出的簽名不是當前網站的host, 固然也不會requestPermission. 而後每一個提示是有id的. 沒有仔細想, 若是須要維護id的話應該比較花功夫. 這個是個極簡版的:

export let notifier = {
    pop: (content, title = "友情提示", ico = "../imgs/ruby_q.png") => {
        chrome.notifications.create({
            type: "basic",
            iconUrl: ico,
            title: title,
            message: content
        }, (cb) => {
            console.log(cb);
        });
    }
};

badge

badge能夠設置顏色, badge內容. 由於badge通常是個消息條數, 提示條數的東西, 限制3個字符(多是4個), 超過長度會被省略號代替.

export let badge = {
    setColor(color) {
        chrome.browserAction.setBadgeBackgroundColor({color: color});
    },
    setText(text, color) {
        chrome.browserAction.setBadgeText({text: text.toString()});
        if (color)
            this.setColor(color);
    },
    clear() {
        chrome.browserAction.setBadgeText({text: ""});
    }
};

儲存

儲存分爲2種, 一種爲chrome.storage.local, 本地儲存, 另一種chrome.storage.sync同步儲存, 若是沒有登陸用戶或者沒有網的時候行爲會與本地儲存一致. 他與h5的storage也是不一樣的. h5的只能存字符串. 他能夠存數組, 對象什麼的. 這個我看來要使用仍是須要作一些處理:

export let storage = {
    set(key, value) {
        let obj = {};
        obj[key] = value;
        return new Promise((resolve) => {
            chrome.storage.sync.set(obj, (callback) => {
                resolve(`ok${callback}`);
            })
        });
    },
    get(key) {
        return new Promise((resolve) => {
            chrome.storage.sync.get(key, (callback) => {
                resolve(callback[key]);
            });
        });
    },
    getAll() {
        return new Promise((resolve) => {
            chrome.storage.sync.get((callback) => {
                resolve(callback);
            });
        })
    },
    sAdd(set, key, value) {
        return this.get(set)
            .then((result) => {
                result = result || {};
                result[key] = value;
                return this.set(set, result);
            });
    },
    sGet(set, key) {
        return this.get(set)
            .then((result) => {
                return (result && result[key]) ? Promise.resolve(result[key]) : Promise.reject("set not found");
            });
    },
    sRem(set, key) {
        return this.get(set)
            .then((result) => {
                if (result && result[key]) {
                    delete result[key];
                    return this.set(set, result);
                } else {
                    return Promise.reject("set not found");
                }
            });
    },
    remove(key) {
        return new Promise((resolve) => {
            chrome.storage.sync.remove(key, (callback) => {
                resolve(callback);
            })
        });
    }
};

告一段落

試水過程當中順帶用vue(試水++) 作了前端(並無畫樣式) 作了一些小功能. 感受不錯. 未來能夠拓展做爲方便的小工具啦.

原文地址

相關文章
相關標籤/搜索