一个你瞅啥的chrome插件

1,612 阅读4分钟

chrome插件,大家都会装上几个,像JSON格式化、postman、页面地址二维码还有很牛逼的油猴,用的很多,但是这玩意怎么写,通过一个小demo了解一下,这个demo就叫what are you looking at。
github地址:你瞅啥。 先看一下怎么用,平时装插件都是去商店下载或者下载crx。
首先打开扩展程序管理

然后在右上角打开开发者模式

这个时候会发现多了一行工具栏,插件下多了id和查看视图,这俩东西后边再说,点左上角的加载已解压的扩展程序,就可以选本地文件夹了。
接下来看一下一个插件都有什么东西

manifest.json

插件的配置文件,这东西是必须的。

{
 // 这个官方已经发布了v3,这里为啥还用2,因为3没跑起来。。。
 "manifest_version": 2,
 // 插件的名称
 "name": "What are you looking at",
 // 插件的版本
 "version": "0.0.1",
 // 插件描述
 "description": "你瞅啥",
 // 图标
 "icons": {
  "16": "icon.png",
  "32": "icon.png",
  "48": "icon.png",
  "128": "icon.png"
 },
 // 这个只要浏览器开了就一直跑
 "background": {
  // v3这里改成了service_worker 按官方文档写但是报了个错
  "page": "background.html"
 },
 // 浏览器右上角图标设置
 "browser_action": {
 	// 图标没生效  不知道因为啥
   "default_icon": "icon.png",
   "default_title": "这是一个你瞅啥的插件",
   "default_popup": "popup.html"
 },
 // 需要直接注入页面的JS
 "content_scripts": [
  {
   // 可以根据页面地址决定是否注入,"<all_urls>" 表示匹配所有地址
   "matches": ["<all_urls>"],
   // 多个JS按顺序注入
   "js": ["js/index.js"],
   "css": ["style.css"],
   // 代码注入的时间,有三个值: "document_start", "document_end", or "document_idle",默认document_idle表示页面空闲时候注入
   "run_at": "document_start"
  }
 ],
 // 权限
 "permissions":
 [
  "contextMenus", // 右键菜单
  "tabs", // 标签
  "notifications", // 通知
  "webRequest", // web请求
  "storage", // 插件本地存储,这个是浏览器全局存储,跨tab
 ],
 // 覆盖浏览器默认页面
 "chrome_url_overrides": {
  // 覆盖浏览器默认的新标签页,momentum就是用的这个
  "newtab": "newtab.html"
 },
 // 这个是插件的配置页
 "options_ui":{
  "page": "options.html",
  // 默认样式
  "chrome_style": true
 },
 // 默认语言 如果写了这个需要写多语言文件
 "default_locale": "zh_CN",
 // devtools页面入口
 "devtools_page": "devtools.html",
 // 插件主页
 "homepage_url": "https://www.baidu.com",
}

常用的差不多就是这些东西,不是很复杂。

background

这东西开了浏览器就一直跑,权限高,有多高呢,除了devtools其他chrome提供的扩展api他都能调用,而且请求不会跨域,不需要后端写cors,其实这个有两种写法:

"background": {
   "page": "background.html"
   // "scripts": ["background.js"]
},

scripts会生成一个html,页面的地址是chrome-extension://id/background.html,中间的id就是插件的id。这个页面虽然可以访问,也可以关闭,但是他有一个一直在跑着,你还看不到。

点击这个可以打开background的开发者工具进行调试。

browser_action

这个是浏览器右上角哪个位置图标的配置 default_icon:图标
default_title:鼠标悬停的title

default_popup:点击图标弹出的页面,生命周期比较短,从点开到关闭

homepage_url

主页的地址,在图标上右键点击

点这可以访问

content_scripts

这个是注入的页面的脚本,可以是js也可以是css,这个东西他和页面共享window,也就是页面上的js能干啥他就能干啥,但是权限比较低,只能调用i18nruntimeextensionstorage,基本上也够用了,其他的也不是不能干,可以和background通信,让background干。

permissions

这个是权限的配置,下边demo里有用法介绍。

options_ui

这个是插件的配置页

点击后会有一个弹窗

因为chrome_style值为true,会有默认样式。

你瞅啥

demo的结构就是这样,比较简单。

{
    "manifest_version": 2,
    "name": "What are you looking at",
    "version": "0.0.1",
    "description": "你瞅啥",
    "icons": {
        "16": "icon.png",
        "32": "icon.png",
        "48": "icon.png",
        "128": "icon.png"
    },
    "background": {
        "page": "background.html"
    },
    "browser_action": {
        "default_icon": "icon.png",
        "default_title": "这是一个你瞅啥的插件",
        "default_popup": "popup.html"
    },
    "homepage_url": "https://www.baidu.com",
    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js": ["js/index.js"],
            "css": ["style.css"],
            "run_at": "document_start"
        }
    ],
    "permissions": [
        "notifications",
        "contextMenus"
    ],
    "options_ui": {
        "page": "options.html",
        "chrome_style": true
    }
}

这是配置文件。 先看content_scripts

const createEl = (text) => {
    const textContainer = document.createElement('div');
    textContainer.className = 'what-are-you-looking-at-text'
    textContainer.innerHTML = text;
    return textContainer;
}

window.onload = () => {
    let timer = null;
    const textArray = [
        '你瞅啥',
        '瞅你咋地',
        '你再瞅我试试',
        '试试就试试'
    ];

    timer = setTimeout(async () => {
        const lookAtContainer = document.createElement('div');
        lookAtContainer.className = 'what-are-you-looking-at';
        document.body.appendChild(lookAtContainer);
        for (const x of textArray) {
            await new Promise((resolve) => {
                setTimeout(() => {
                    lookAtContainer.innerHTML = '';
                    lookAtContainer.appendChild(createEl(x));
                    resolve();
                }, 3000);
            })
        }

        setTimeout(() => {
            chrome.runtime.sendMessage({message: '大哥你让人揍了'}, (response) => {
                console.log('response: ' + response);
            });
            lookAtContainer.onclick = () => {
                document.body.removeChild(lookAtContainer);
            }
        }, 1000);
    }, 10000);
}

比较简单,整个流程就是打开页面10秒之后会有一个半透明的弹窗,内容就是最常用的打招呼对话,在对话结束之后会给background发一条消息,被人揍了。
再看background,接收到消息之后,给content_scripts回了一条知道了的消息,并发送一个被人揍了的浏览器通知。

chrome.runtime.onInstalled.addListener(function() {
    chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
        console.log(request);
        console.log(sender);
        sendResponse('我知道了');
        chrome.notifications.create(null, {
            type: 'basic',
            iconUrl: 'icon.png',
            title: '这是标题',
            message: '大哥你让人揍了'
        });
    });
});

chrome.runtime.onInstalled会在浏览器启动的时候触发。 chrome.runtime.onMessagechrome.tabs.onMessagechrome.tabs.connectchrome.runtime.connect为各js之间的主要通信方式,这里用了chrome.runtime.onMessage

这里用到了通知,是要在permissions里开的,然后电脑设置允许chrome通知,才会有。
再看一下permissions的右键菜单。

"permissions": [
    "contextMenus"
]

配置文件里开启右键菜单权限

chrome.runtime.onInstalled.addListener(function() {
    chrome.contextMenus.create({
        "id": "contextMenu",
        "title": "你瞅啥右键菜单",
        onclick: () => {
            console.log('右键点击了你瞅啥');
        }
    });
});

background里创建右键菜单。

点击之后会在background控制台打印右键点击了你瞅啥
更详细的请看官方文档