网页网站您现在的位置是:首页 > 博客日志 > 网页网站

Chrome扩展插件开发极简入门手册,5分钟学会Chrome插件开发

<a href='mailto:'>微wx笑</a>的头像微wx笑 2022-09-29网页网站 4 0关键字: Chrome  插件  extensions  

有一些功能,虽然通过开发者工具,在控制台执行代码也能完成,但是经常需要使用的话,每次重新打开窗口或刷新一下网页就需要重新执行一下,比较麻烦,如果把它们打包成一个Chrome扩展插件,使用起来就比较方便了。

有一些功能,虽然通过开发者工具,在控制台执行代码也能完成,但是经常需要使用的话,每次重新打开窗口或刷新一下网页就需要重新执行一下,比较麻烦,如果把它们打包成一个Chrome扩展插件,使用起来就比较方便了。L7U无知


L7U无知

Chrome是个非常牛逼的浏览器,速度快,界面清爽,对开发人员友好。而且提供了种类齐全且高质的插件。今天我们就来简单聊一聊如何开发chrome插件。L7U无知


L7U无知

基本知识L7U无知

在具体的开发之前,我们先来科普一些基础知识。L7U无知


L7U无知

现阶段的chrome的应用商店中,将插件(这里说的插件指代chrome应用的所有分类,下文亦同)分为如下几种,包括应用、游戏、扩展程序、主题背景。而且插件的种类多种多样,保罗万象,基本上都能找到你想要的功能的插件。L7U无知


L7U无知

文件结构L7U无知

在应用商店中下载下来的插件基本上都是以.crx为文件后缀,该文件其实就是一个压缩包,包括插件所需要的html、css、javascript、图片资源等等文件。L7U无知

其中,L7U无知

  • manifest.json是整个插件的功能及文件配置清单,非常重要。L7U无知

  • static目录是放置整个插件的静态资源文件的,包括css、js、图片等等资源L7U无知

  • template目录是放置整个插件的功能页面模板的。L7U无知

  • _locales目录是放置整个插件的国际化语言脚本的。L7U无知

一般来说,清单文件manifest.json文件是必须的,且必须放在插件开发目录的根目录上。其他的目录都可以自定义。L7U无知

manifest.json文件

清单文件的作用是提供插件的各种信息,例如插件能够做的事情,以及插件的文件配置等等信息。下面是一个清单文件的示例,L7U无知

{
  "name": "我的扩展程序",
  "version": "2.1",
  "manifest_version": 2,
  "description": "从Google获得信息。",
  "icons": {
    "128": "icon_128.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["bg.js"]
  },
  "permissions": ["http://*.google.com/", "https://*.google.com/"],
  "browser_action": {
    "default_title": "",
    "default_icon": "icon_19.png",
    "default_popup": "popup.html"
  }
}

两种功能级别

chrome插件一般有两种,一种是显示在浏览器工具栏的按钮,称之为Browser Actions一种是显示在页面地址栏按钮的被称之为Page ActionsL7U无知

这是page actions:L7U无知


L7U无知

这是browser actions:L7U无知


L7U无知


L7U无知

Page Actions 与 Browser Actions 的区别就是 Page Actions 并不是在每个页面上都是有用的,它必须在特定的页面中插件功能才能使用。L7U无知

这两种用户面界面分别对应manifest.json中的browser_actionpage_action字段。L7U无知

弹出窗口和后台页面

弹出窗口一般用于插件和用户的交互,而后台页面一般用于插件本身做一些额外的事情。比如有时候,插件需要联网进行数据同步等操作,这种操作用户是无感知的,所有就要求插件需要有一个后台页面来运行这部分的逻辑。L7U无知

其实后台页面还可以分为持久运行的后端页面和事件页面,这里对这两者就不多做说明了,更多的内容可以参阅具体的文档。L7U无知

其他

chrome插件的相关知识,远远不止上面介绍的几点,比如邮件菜单、插件与浏览器之间的交互、内容安全(CSP)、消息传递、国际化、部署与托管等等方面,由于篇幅原因,这里将不会作过多的描述。L7U无知

自己做一个

有了上面的基础知识之后,我们就可以尝试自己来做一个chrome插件玩玩了。L7U无知

首先我们新建一个文件夹叫做 extensions,作为插件开发的工作目录,再建一个子文件夹sina-plugin,这个文件夹下面存放插件所有文件,然后在目录中新建清单文件,manifest.json文件内容如下:L7U无知

{
    "name": "sina-plugin",
    "version": "0.9.0",
    "manifest_version": 2,
    "description": "chrome plugin demo",
    "browser_action": {
        "default_icon": "icon.png",
        "default_title": "Todo List",
        "default_popup": "popup.html"
    }
}

在清单文件中,我们定义了插件的名称、版本、描述,插件的浏览器按钮行为以及插件所需要注入的脚本文件。按钮行为中还包括了默认的按钮图标、按钮标题(鼠标悬停时显示)以及默认的弹出框popup.htmlL7U无知

注意:新版的chrome插件开发需要在清单文件中制定mainfest_version为2。L7U无知

这里的弹出框其实就是我们这个插件与用户交互的主要界面,它其实就是一个html页面。不过这个popup.html文件并不需要<html></html><body></body><head></head>这样的标签。popup.html文件内容如下,L7U无知

<style>
    body {
        width: 150px;
    }
    #add-new-item {
        cursor: pointer;
        color: #CCC;
    }
    .hide {
        display: none;
    }
    .show {
        display: block;
    }
    .item {
        cursor: pointer;
        margin: 5px 0;
    }
    .item input {
        display: inline-block;
        width: 12px;
        height: 12px;
    }
    input {
        width: 120px;
    }
</style>
<div id="add-new-item">添加新项</div>
<div id="add-new-item-input" class="hide">
    <input type="text" id="new-item-title" placeholder="添加新任务"/>
</div>
<div id="item-list"></div>
<script type="text/javascript" src="main.js"></script>

这个html文件其实很简单(chrome插件的html页面往往都非常简单,都是一些列表的展示,轻量的输入控件等等),而且为了简便,我把弹出窗的样式直接写在html中了。L7U无知

最后一行我们使用外链的方式加载了popup页面的交互逻辑。main.js内容也很简单,如下L7U无知

(function () {
    var $ = function (id) {
        return document.getElementById(id);
    };
    var Tasks = {
        show: function (obj) {
            obj.className = '';
            return this;
        },
        hide: function (obj) {
            obj.className = 'hide';
            return this;
        },
        $addNewItem: $('add-new-item'),
        $addNewItemInput: $('add-new-item-input'),
        $itemList: $('item-list'),
        $newItemTitle: $('new-item-title'),
        init: function () {
            //打开添加文本框
            Tasks.$addNewItem.addEventListener('click', function () {
                Tasks.show(Tasks.$addNewItemInput).hide(Tasks.$addNewItem);
                Tasks.$newItemTitle.focus();
            }, true);
            //回车添加任务
            Tasks.$newItemTitle.addEventListener('keyup', function (ev) {
                var ev = ev || window.event;
                if (ev.keyCode == 13) {
                    //TODO:写入本地数据
                    var task = Tasks.$newItemTitle.value;
                    Tasks.AppendHtml(task);
                    Tasks.$newItemTitle.value = '';
                    Tasks.hide(Tasks.$addNewItemInput).show(Tasks.$addNewItem);
                }
                ev.preventDefault();
            }, true);
            //取消添加
            Tasks.$newItemTitle.addEventListener('blur', function () {
                Tasks.$newItemTitle.value = '';
                Tasks.hide(Tasks.$addNewItemInput).show(Tasks.$addNewItem);
            }, true);
            //TODO 初始化数据,加载本地数据,生成html
        },
        //增加
        Add: function () {
            //TODO
        },
        //修改
        Edit: function () {
            //TODO
        },
        //删除
        Del: function () {
            //TODO
        },
        AppendHtml: function (title) {
            var oDiv = document.createElement('div');
            oDiv.className = 'item item-todo';
            var oInput = document.createElement('input');
            oInput.type = 'checkbox';
            var oTitle = document.createElement('span');
            oTitle.innerHTML = title;
            oDiv.appendChild(oInput);
            oDiv.appendChild(oTitle);
            Tasks.$itemList.appendChild(oDiv);
            oDiv.addEventListener('click', function () {
                //TODO
            }, true);
        },
        RemoveHtml: function () {
            //TODO
        }
    }
    Tasks.init();
})();

在这段js中,我们声明了一个Tasks对象,这个对象包括了一系列的功能方法,当然有部分未实现,不过核心功能都实现了。在Tasks.init方法中,我们给一个操作实体(一个div元素)注册了点击事件,当触发点击事件时,我们将会展示一个输入框让用户输入任务描述,通过回车键来添加用户刚输入的任务。好了,这就是sina-plugin插件的基本功能。L7U无知

打包L7U无知

现在就可以先尝试把它打包装到自己的Chrome里。L7U无知

首先打开Chrome-工具-扩展程序,展开开发人员模式,打到“打包扩展程序”按钮:L7U无知

image.pngL7U无知

点击“打包扩展程序…”,弹出打包选择文件窗口,在扩展程序根目标中找到我们建立的文件夹,私有密码文件第一次不用选择:L7U无知

image.pngL7U无知

第二次打包就要选择私钥文件了,否则你会看到错误提示:打包扩展程序错误 指定扩展程序的私有密钥已存在。请重复使用该密钥,或者先删除它。L7U无知

点击打包扩展程序,它会在上一级生成sina-plugin.crx和sina-plugin.pem,sina-plugin.pem是程序签名文件,在新版本的开发中还需要这个文件,不要删除它。把sina-plugin.crx拖进Chrome窗体内,就会把这个应用sina-plugin安装在Chrome里。L7U无知

还可以通过“加载已解压的扩展程序”功能直接把自己写的插件安装到Chrome里。L7U无知

注意:清单文件中指定了 "default_icon": "icon.png",  icon.png必须存在于sina-plugin目录下,如果找不到的话,会弹出提示:L7U无知

6a46adb7c46a6e4ac1b389928284a81.jpgL7U无知

插件安装成功后,我们就能在浏览器上看到它了L7U无知

扩展插件比较多的话,默认会隐藏,需要点击扩展程序按钮,找到对应的扩展插件,选择把它固定在浏览器工具栏上。L7U无知

image.pngL7U无知


L7U无知

小结

好了,至此我们总算完成一个简陋的chrome插件的开发了。功能虽然简陋,但是基本上所有的chrome插件开发都是遵循这条路。本文示例的代码中有许多的TODO,其实我们可以将这个todo插件做的更加复杂,比如可以采用localstorage来存储数据,甚至可以使用网络来存储数据。至于更多的内容,本文就不再作过多的阐述了,因为本文毕竟是简要指南嘛。L7U无知


L7U无知

要实现一些更强大实用的功能,还需要为扩展程序声明权限,参考:Chrome扩展程序开发 declare permissions 声明权限L7U无知

本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.com/blog/web/2022-09-29/1393.html

很赞哦! () 有话说 ()