published on in 前端技术
tags: Chrome

Chrome插件开发

关于谷歌浏览器插件开发的详细内容,可以访问谷歌的文档“Getting Start”,本文主要介绍下简单Chrome插件开发。

简单的Chrome插件包含三个文件,一个manifest.json是配置文件,一个js文件,一个图标。 来看一下manifest.json中的基本配置:

{
    "name": "test",//插件名称
    "description": "alert",//插件描述
    "version": "0.0.1",
    "permissions": ["tabs","<all_urls>"],
    "browser_action": {
        "default_icon": "test.png"//插件图标,xx.jpg
    },
    "content_scripts": [{
        "matches": [
            "http://*/*",
            "https://*/*"
        ],
        "js": ["load.js"],//js文件
        "run_at": "document_end"//在页面加载完时运行
    }], 
    "manifest_version":2
}

在load.js中可以对加载完的页面做任何操作

编写完成后,把这三个文件放在一个文件夹下,打开Chrome设置,选择左侧Extensions,点击“Load unpacked extension…”按钮将前面的文件夹加载进来即可。

到这里,我们的插件只能在进入页面的时候进行一些操作,但是少了关键的菜单,下面就来弄个菜单。

第一步,修改manifest,在browser_action中添加一项:

"browser_action": {
    "default_icon": "test.png",
    "default_popup":"popup.html"
}

其实菜单也是一个html文件,所以是通过html、css来定义它的样式,通过绑定事件来实现功能,popup.html:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>alert</title>
        <style>
        div{
            width:100px;
            height:20px;
            line-height:20px;
            text-align:center;
            font-family: sans-serif;
            font-size:0.8em;
            background:#F3F3F3;
            margin-bottom:4px;
            cursor:pointer;
            border-radius:3px;
        }
        div:hover{
            background:#CCCCCC;
        }
        </style>
    </head>
    <body>
        <div id="alert">alert</div>
        <script src="popup.js"></script>
    </body>
</html>

样式比较简单,只有一个div,也就是一个按钮,通过引入popup.js文件来绑定事件,这里必须通过script标签引入外部的js,而不能写內联js,不然会报错。popup.js:

document.querySelector("#alert").addEventListener("click",function(){
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, {action: "showTitle"}, function(response) {
            console.log("ok");
        });
    });
});

给alert绑定了click事件,内部的实现比较有意思,通过chrome.tabs.query来获取当前的tab,然后通过chrome.tabs.sendMessage给当前tab发送消息,popup和content之间就是通过message来通信的,为什么要搞的这么麻烦呢,因为popup和content是相互隔离的,是两个独立的页面,当然不能在一个页面调用另一个页面的方法。load.js:

function showTitle(){
    alert(document.title);
}

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {  
    var action = request.action;
    switch(action){
        case "showTitle":
            showTitle();
            break;
        default:
            console.log("unknown action");
            break;
    }
});

console.log("loaded");

load.js里面,通过chrome.runtime.onMessage.addListener来添加一个message监听器,request就是上面sendMessage的第二个参数,通过action的不同调用不同的方法。

按照上面的实现,我们发现只有刷新页面的时候生效,切换tab后就无效了,这时候就要用上了background了,在manifest里面添加background和权限:

"permissions": ["tabs","<all_urls>","activeTab"],
"background":{
    "scripts":["background.js"]
}

background的js能够运行在浏览器后台,background.js:

chrome.tabs.onActivated.addListener(function(activeInfo) {
    chrome.tabs.get(activeInfo.tabId, function (tab) {
        chrome.tabs.executeScript(tab.id,{file:"load.js"});
    });
});

这里绑定了onActivated事件,即在浏览器切换时会出发,把load.js加载进来,同时我们也要修改load.js避免重复加载,load.js:

if(!window.loaded){
    console.log("loaded");
    window.loaded = true;

    function showTitle(){
        alert(document.title);
    }

    chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {  
        var action = request.action;
        switch(action){
            case "showTitle":
                showTitle();
                break;
            default:
                console.log("unknown action");
                break;
        }
    });
}

完整的代码放在github上:https://github.com/homfen/chrome-extension-demo

所以开发一个Chrome插件也不难。