前言

作为一个前端开发者,学习谷歌插件的开发也是十分必要的

导入

开发一个谷歌插件的第一步就是先学会导入,首先这里你先创建一个任意名字的文件夹,在创建一个入口文件manifest.json,插件的配置都是在这里面进行配置的,主题就是一个json对象,格式大概如下

{
  "name": "demo",    //设置插件名
  "manifest_version": 2,   //版本,这个是固定的
  "version": "1.0.0",    //插件版本,用于迭代识别
  "description": "a little demo",   //插件描述
  "icons": {          //设置插件图标不同大小对应的图片
    "16": "img/icon.png",
    "48": "img/icon.png",
    "128": "img/icon.png"
  },
  "browser_action": {    //我个人理解为插件显示在菜单栏时候的行为,设置标题内容页等
    "default_title": "图标标题",     
    "default_icon": {
      "16": "img/icon.png"
    },
    "default_popup": "popup.html"
  }
  "background": {
    "page": "back.html"    //指定后台页
  }
}

之后你就可以导入了,我这里创建的文件夹叫demo,导入步骤
右上角菜单→更多工具→拓展程序,之后跳转到扩展程序页面,打开开发者模式,选择加载已解压的扩展程序,选中刚才包含入口文件的文件夹即可
谷歌插件开发-DESTLIVE

后台页

对于后台页我的理解为后台页就是一直驻留在浏览器后台的页面可以时刻监听浏览器的各种行为
前面可以看到我们给browser_action的default_popup设置为popup.html,这里我把popup.html的代码贴出来

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>demo</title>
    <style>
      body {
        width: 500px;
        min-height: 200px;
      }
    </style>
  </head>
  <body>
    <h2>呵呵</h2>
    <h2>功能</h2>
    <br />
    <div>
      <ol>
        <li><a href="#" id="openback">打开后台页面</a></li>
        <li><a href="#" id="getbacktitle">获取后台页标题</a></li>
        <li><a href="#" id="setbacktitle">设置后台页标题</a></li>
        <li><a href="#" id="callbackjs">调用后台页js</a></li>
      </ol>
    </div>
    <script type="text/javascript" src="popup.js"></script>
  </body>
</html>

popup.js中的代码

let openPage = document.getElementById("openback");
openPage.addEventListener("click", () => {
  window.open(chrome.extension.getURL("back.html"));
});

let getTitle = document.getElementById("getbacktitle");
getTitle.addEventListener("click", () => {
  let bg = chrome.extension.getBackgroundPage();
  alert(bg.document.title);
});

let setTitle = document.getElementById("setbacktitle");
setTitle.addEventListener("click", () => {
  let title = prompt("请输入后天页新标题", "新标题");
  let bg = chrome.extension.getBackgroundPage();
  bg.document.title = title;
  alert(bg.document.title);
});

后台页back.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>背景页面</title>
  </head>
  <body>
    <h2>背景页内容</h2>
    <script type="text/javascript" src="back.js"></script>
  </body>
</html>

显示在右上角的效果就是,之后点击就可以实现popup中监听器中监听事件发生时的指定动作
谷歌插件开发-DESTLIVE

调用后台页中的js

用到这个首先需要设置各种权限,例如浏览器分栏权限和浏览器跨域权限(因为插件对应着浏览器不同网站),为manifest.json添加字段

"permissions": [
    "tabs",
    "*://*/*",
    "http://*/*",
    "https://*/*"
   ]

后台页中script标签代码

function backjs() {
  //chrome.tabs  使用api和浏览器选项卡进行交互
  chrome.tabs.getSelected(null, (tab) => {
      //传进来的参数是当前标签页
    let title = tab.title;
    //执行代码语句
    chrome.tabs.executeScript(null, {
      code: "javascript:alert('" + title + "')",
    });
  });
}

popup.js追加代码

let callBack = document.getElementById("callbackjs");
callBack.addEventListener("click", () => {
  let bg = chrome.extension.getBackgroundPage();
  bg.backjs();
});

之后点击调用后台页js时即可弹出含有网页标题的警示框

百度自动搜索案例
实现点击调用后台页js百度首页自动搜索指定内容

function backjs() {
  //chrome.tabs  使用api和浏览器选项卡进行交互
  chrome.tabs.getSelected(null, (tab) => {
    //传进来的参数是当前标签页
    let title = tab.title;
    //执行代码语句
    // chrome.tabs.executeScript(null, {
    //   code: "javascript:alert('" + title + "')",
    // });
    //这里通过审查元素直接获取百度的输入框和搜索按钮的id
    chrome.tabs.executeScript(null, {
      code:
        "let ipt = document.getElementById('kw');  ipt.value = '小天才'; let btn = document.getElementById('su'); btn.click() ",
    });
  });
}

升级版
manifest添加

"content_scripts": [    //js注入
    {
      "matches": ["<all_urls>"],    //所有地址
      "js": ["auto.js"],			//执行的js文件
      "run_at": "document_start"
    }
  ]

auto.js的代码,形成一进页面就搜索的效果

document.addEventListener("DOMContentLoaded", function () {
  const theUrl = window.location;
  if (theUrl == "https://www.baidu.com/") {  //不做判断的话会一直重复执行
    let ipt = document.getElementById("kw");
    ipt.value = "猪";
    let btn = document.getElementById("su");
    btn.click();
  }
});

鼠标右键菜单

permission中添加字段contextMenus(菜单权限)
把back.js文件改为

chrome.contextMenus.create({
  title: "自动搜索靓仔",
  onclick: function () {
    chrome.tabs.executeScript(null, {
      code:
        "let ipt = document.getElementById('kw');  ipt.value = '靓仔'; let btn = document.getElementById('su'); btn.click()",
    });
  },
});

右键菜单多级

chrome.contextMenus.create({
  title: "自动搜索",
  id: "1",
  contexts: ["selection", "editable"],  //右键菜单项将会在这个列表指定的上下文类型中显示
  onclick: function () {
    chrome.tabs.executeScript(null, {
      code:
        "let ipt = document.getElementById('kw');  ipt.value = '靓仔'; let btn = document.getElementById('su'); btn.click()",
    });
  },
  // documentUrlPatterns: ["https://*.baidu.com/*"],  //这使得右键菜单只在匹配此模式的url页面上生效
});
chrome.contextMenus.create({
  title: "自动搜索靓仔",
  parentId: "1",
  type: "radio",  //右键菜单项的类型
  contexts: ["selection", "editable"],
  onclick: function () {
    chrome.tabs.executeScript(null, {
      code:
        "let ipt = document.getElementById('kw');  ipt.value = '靓仔'; let btn = document.getElementById('su'); btn.click()",
    });
  },
  // documentUrlPatterns: ["https://*.baidu.com/*"],
});
chrome.contextMenus.create({
  title: "自动搜索叼毛",
  parentId: "1",
  type: "radio",
  contexts: ["selection", "editable"],
  onclick: function () {
    chrome.tabs.executeScript(null, {
      code:
        "let ipt = document.getElementById('kw');  ipt.value = '叼毛'; let btn = document.getElementById('su'); btn.click()",
    });
  },
  // documentUrlPatterns: ["https://*.baidu.com/*"],
});

获得插件列表

permissions添加字段management
在back.js中将函数backjs改写为

function backjs() {
  chrome.management.getAll((res) => {
    alert(JSON.stringify(res));
  });
}

弹框展示的就是各插件的信息

锁定打开新标签页显示自己网页

在manifest.json中添加字段

"chrome_url_overrides": {
    "newtab": "new.html"
  }

new.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="refresh" content="0.1;url=http://www.baidu.com" />
    <title>Document</title>
  </head>
  <body></body>
</html>

这样网页添加新页面打开的都是百度

设置插件图标

在popup.html添加菜单选项

<p>功能2</p>
      <ol>
        <li><a href="#" id="showbadge">显示badge</a></li>
        <li><a href="#" id="hidebadge">隐藏badge</a></li>
      </ol>

在popup.js中添加代码

let showbadge = document.getElementById("showbadge");
showbadge.addEventListener("click", () => {
  chrome.browserAction.setBadgeText({text: "奥特曼"});
  chrome.browserAction.setBadgeBackgroundColor({color: [0, 255, 0, 255]});
});

let hidebadge = document.getElementById("hidebadge");
hidebadge.addEventListener("click", () => {
  chrome.browserAction.setBadgeText({text: ""});
  chrome.browserAction.setBadgeBackgroundColor({color: [0, 0, 0, 0]});
});

即可显示菜单栏中图标的徽标
谷歌插件开发-DESTLIVE

地址栏实现百度搜索

在back.js中添加如下代码

chrome.omnibox.onInputChanged.addListener((text, suggest) => {
  //text为输入的文字
  if (!text) {
    return;
  }
  if (text == "靓仔") {
    suggest([
      {content: text + "无语", description: "你要找”靓仔无语“?"},
      {content: text + "语塞", description: "你要找”靓仔语塞“?"},
      {content: text + "过敏", description: "你要找”靓仔过敏“?"},
    ]);
  }
});
chrome.omnibox.onInputEntered.addListener((text) => {
  if (!text) {
    return;
  }
  let href = "";
  //startWith表示以什么关键字开头
  if (text.startsWith("靓仔")) {
    //表示如果text以“靓仔”开头
    href =
      "https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=" +
      text;
    openUrl(href);
  }
});
//获取当前页id
function getCurrentTabId(callback) {
  chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
    if (callback) {
      callback(tabs.length ? tabs[0].id : null);
    }
  });
}
//打开页面
function openUrl(url) {
  getCurrentTabId((tabId) => {
    chrome.tabs.update(tabId, {url: url});
  });
}

桌面通知

manifest.json的permissions中添加字段notifications

let opt = {
    type: "basic",
    title: "是兄弟就来砍我!",
    message: "我是渣渣辉,是兄弟就来砍我~",
    iconUrl: "img/icons.png",
  };
  chrome.notifications.create("", opt);

网页CSS注入修改

这类操作都需要先获取网页id

function getCurrentTabId(callback) {
  chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
    if (callback) {
      callback(tabs.length ? tabs[0].id : null);
    }
  });
}
function executeScriptToCurrentTab(scriptcode) {
  getCurrentTabId((tabId) => {
    chrome.tabs.executeScript(tabId, {code: scriptcode});
  });
}

let updateCss = document.getElementById("updateCss");
updateCss.addEventListener("click", () => {
  executeScriptToCurrentTab('document.body.style.fontSize="30px";');
  executeScriptToCurrentTab('document.body.style.backgroundColor="blue";');
});

插件打包与CRX文件安装

点击打包扩展程序并选择项目目录
谷歌插件开发-DESTLIVE
打包后生成两个文件,crx为打包文件,pem为私密文件
谷歌插件开发-DESTLIVE
别人要使用的话把crx后缀改成zip再解压,就是跟之前一样的项目文件了

在特定页显示插件

manifest.json中browser_action改为page——action
permissions中添加字段declarativeContent
在back.js中添加如下代码,实现只有在baidu.com相关页面插件才有效

chrome.runtime.onInstalled.addListener(() => {
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
    chrome.declarativeContent.onPageChanged.addRules([
      {
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: {urlContains: "baidu.com"},
          }),
        ],
        actions: [new chrome.declarativeContent.ShowPageAction()],
      },
    ]);
  });
});

为百度页添加自己的搜索按键

manifest.json中添加字段"web_accessible_resources":["inject.js"],创建inject.js文件
将auto.js代码修改为如下

document.addEventListener("DOMContentLoaded", function () {
  jsPath = "inject.js";
  let tmp = document.createElement("script");
  tmp.src = chrome.extension.getURL(jsPath);
  tmp.setAttribute("type", "text/javascript"); //添加属性
  document.head.appendChild(tmp); //为head标签添加script标签
});

inject.js代码

let btn = document.getElementById("su");
btn.after("<input type=button class='bg s_btn' value='靓仔' id=liangzai/>");
let btnNew = document.getElementById("liangzai");
let ipt = document.getElementById("kw");
btnNew.addEventListener("click", () => {
  kw.value = "靓仔";
  btn.click();
});

打开百度显示自己的文字

inject.js代码修改为如下,即可改变默认现实的输入内容和按钮文字

let ipt = document.getElementById("kw");
ipt.setAttribute("value", "靓仔");
let btn = document.getElementById("su");
btn.setAttribute("value", "靓仔一下");