Chrome插件开发_V3_浏览器扩展插件基础教程

news2024/12/24 20:26:48

文章目录

  • 一、简介
  • 二、核心介绍
  • 三、自定义页面背景色
  • 三、设置页面背景图(web_accessible_resources)
  • 四、设置徽章(Badge)
  • 五、桌面通知
  • 六、消息通信
  • 七、自定义右键菜单(添加、更新、删除)
  • 八、Omnibox
  • 九、浏览器交互
  • 十、根据 url 匹配 popup 窗口能否打开
  • 十一、点击插件跳转至扩展页
  • 十二、项目地址


一、简介

Chrome 插件(浏览器右上角的扩展插件)实际上是是更底层的浏览器功能扩展,是一个用Web技术开发、用来增强浏览器功能的软件,它其实就是一个由HTML、CSS、JS、图片等资源组成的一个.crx后缀的压缩包;

提供两个文档(内容可能不都是最新的)
文档:http://chrome.cenchy.com/tabs.html
文档:https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json

二、核心介绍

🚨 manifest.json

这是一个 Chrome 插件最重要也是必不可少的文件,用来配置所有和插件相关的配置,必须放在根目录。其中,manifest_version、name、version 这三个是必不可少的,description 和 icons 是推荐的;

下面给出的是一些常见的配置项,均有中文注释;

字段名说明
manifest_version清单文件的版本,这个必须写,我们这里写 3
name插件的名称
version插件的版本
description插件描述
icons图标
background配置插件在后台运行的js代码
content_scripts定义一系列匹配规则,当URL被匹配时,自动执行js
permissions插件运行需要的权限
action浏览器右上角图标设置
options_page右键插件图标的 -> 选项页面,允许用户进行个性化设置
omnibox向地址栏注册一个关键字以提供搜索建议,只能设置一个关键字
web_accessible_resources用来指定可从扩展程序中访问的资源,包括 HTML、图片、CSS、JavaScript 等文件
theme主题配置

Chrome 插件没有严格的项目结构要求,只要保证本目录有一个 manifest.json 即可,我们来创建一个插件的清单;

然后创建 icons 文件夹,用来存放所用到的图标;

{
    "name": "CustChromePlug",
    "version": "1.0",
    "manifest_version": 3,
    "description": "Customize Google plug-in demo !",
    "icons": {
        "16": "icons/icon16.png",
        "32": "icons/icon32.png",
        "48": "icons/icon48.png",
        "64": "icons/icon64.png",
        "128": "icons/icon128.png"
    }
}

加载扩展插件

加载扩展插件可以通过 Chrome 进行本地源码加载,也可以直接将生成的 crm 拖拽加载,或者注册 Chrome 扩展开发者上传商店,通过商店加载扩展程序;

  • 当前来说我们可以点击 浏览器右上角菜单 > 更多工具 > 扩展程序进入 插件管理页面,也可以直接在地址栏输入 chrome://extensions 访问;
  • 右上角开启 - 开发者模式;
  • 左上角点击 - 加载已解压的扩展程序,选择我们刚刚创建的项目;
  • 浏览器右上角有一个碎片标识可以管理所有的扩展程序,我们可以将我们新创建的程序固定到浏览器右上角(现在可以看到插件已经加载完成,但是图标是灰色,不着急我们接着向下走);

在这里插入图片描述

🚨 content-scripts

所谓 content-scripts,其实就是 Chrome 插件中向页面注入脚本的一种形式(虽然名为script,其实还可以包括 css 的),借助content-scripts 我们可以实现通过配置的方式轻松向指定页面注入 JS 和 CSS(如果需要动态注入,可以参考下文);通过使用标准的 DOM,它们可以获取浏览器所访问页面的详细信息,并可以修改这些信息;

字段名类型说明
matchesarray of strings必须,定义哪些页面需要注入content script,具体见匹配模式
cssarray of strings可选,需要向匹配页面中注入的CSS文件,按照定义的顺序依次注入
jsarray of strings可选,需要向页面中注入的 javascript 文件,按定义顺序注入。
run_atstring可选。 控制content script注入的时机。可以是document_start, document_end或者document_idle。默认是document_idle。如果是document_start, 文件将在所有CSS加载完毕,但是没有创建DOM并且没有运行任何脚本的时候注入。如果是document_end,则文件将在创建完DOM之后,但还没有加载类似于图片或frame等的子资源前立刻注入。如果是document_idle,浏览器会在document_end和发出window.onload事件之间的某个时机注入。具体的时机取决与文档加载的复杂度,为加快页面加载而优化
include_globsarray of string可选(包含)。控制将content_script注入到哪些匹配的页面中
exclude_globsarray of string可选(排除)。控制将content_script注入到哪些匹配的页面中

打开我们上面的创建的清单 manifest.json, 添加 content_scripts 配置,当访问 “百度” 的网页时我们添加一个背景色

{
    "content_scripts": [
        {
            "matches": [
                "https://www.baidu.com/*",
                "http://www.baidu.com/*"
            ],
            "js": [
                "js/baidu.js"
            ],
            "css": [],
            "run_at": "document_idle"
        }
    ]
}

创建 js 文件夹,编写 baidu.js 文件

let ghtml = document.getElementsByTagName('html')[0],
    gdiv = document.createElement('div');
gdiv.id = 'changdiv'
gdiv.style.position = 'fixed';
gdiv.style.width = '100%';
gdiv.style.height = '100%';
gdiv.style.top = '0px';
gdiv.style.left = '0px';
gdiv.style.opacity = '0.1';
gdiv.style.zIndex = '-1';
gdiv.style.backgroundColor = 'deepskyblue';

ghtml.appendChild(gdiv);

编写完成后,打开扩展程序,重新加载插件,然后访问百度页面,就可看到效果了;

在这里插入图片描述
在这里插入图片描述

🚨 popup

popup 是点击 action 图标时打开的一个小窗口网页,焦点离开网页就立即关闭,一般用来做一些临时性的交互;

popup 可以包含任意你想要的HTML内容,并且会自适应大小。可以通过 default_popup 字段来指定 popup 页面,也可以调用setPopup() 方法

打开我们上面的创建的清单 manifest.json, 配置 popup 页面

{
    "action": {
        "default_title": "CustChromePlug popup",
        "default_popup": "popup.html",
        "default_icon": {
            "16": "icons/icon16.png",
            "32": "icons/icon32.png",
            "48": "icons/icon48.png",
            "64": "icons/icon64.png",
            "128": "icons/icon128.png"
        }
    }
}

编写 popup.html

<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>

<body>
    <div>我是 popup.html </div>
</body>

</html>

点击插件图标即可看到 popup 页面,同时插件 icon 也应该有颜色了;

在这里插入图片描述

🚨 background

background 是一个常驻的页面,它的生命周期是插件中所有类型页面中最长的,它随着浏览器的打开而打开,随着浏览器的关闭而关闭,所以通常把需要一直运行的、启动就运行的、全局的代码放在background里面;

打开我们上面的创建的清单 manifest.json,配置 background, chrome.runtime.onInstalled 事件发生后,将颜色数据进行存储,存储成功后会在插件控制台页打印 “ [Coloring] default color is set to: …“

注意:chrome.runtime.onInstalled ,在 onInstalled 侦听器中,它只能在安装/更新后立即工作不到一分钟,所以需要长时间监听的动作/事件不要放在里面

"background": {
    "service_worker": "background.js"
},

编写 background.js

const color = "rgb(153, 196, 230, 0.2)";

chrome.runtime.onInstalled.addListener(() => {

    chrome.storage.sync.set({ color }, function () {
        // 缓存默认颜色
        console.log(`[Coloring] default color is set to: ${color}`);
    });

});

重新加载插件之后发现并没有输入,还有个错;

  • 点击 Service Worker 可打开控制台
  • 点击插件,弹出 popup 窗口网页,鼠标右击 > 检测,也可打开控制台
  • 鼠标放大插件图标,鼠标右击 查看弹出元素,也可打开控制台

在这里插入图片描述
这个错是因为我们没有给与插件运行所需要的权限

"permissions": [
     "storage"
 ]

配置权限之后重新加载插件,即可看到打印信息(或者移除插件重新添加);
在这里插入图片描述
🚨 options_page

options_page 是为了让用户设定自己的扩展功能,而提供一个选项页;

打开我们上面的创建的清单 manifest.json,配置 options_page

"options_page": "options.html"

编写 options.html

<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title>My Test Extension Options</title>
</head>

<body>
    <h1>测试扩展选项页面</h1>
</body>

</html>

右击插件 > 点击 “选项” 即可以跳转 options.html(也可以点击插件直接跳转至选项页面,chrome.runtime.openOptionsPage(),这个方法放到下面的案例中演示)

在这里插入图片描述

🚨 theme

主题是一种特殊的扩展,可以用来改变整个浏览器的外观;主题和标准扩展的打包方式类似,但是主题中不能包含JavaScript或者HTML代码;

下面是示例代码,用来生成一个特定的主题,供大家参考;

"theme": {
    "images" : {
      "theme_frame" : "images/theme_frame_camo.png",
      "theme_frame_overlay" : "images/theme_frame_stripe.png",
      "theme_toolbar" : "images/theme_toolbar_camo.png",
      "theme_ntp_background" : "images/theme_ntp_background_norepeat.png",
      "theme_ntp_attribution" : "images/attribution.png"
    },
    "colors" : {
      "frame" : [71, 105, 91],
      "toolbar" : [207, 221, 192],
      "ntp_text" : [20, 40, 0],
      "ntp_link" : [36, 70, 0],
      "ntp_section" : [207, 221, 192],
      "button_background" : [255, 255, 255]
    },
    "tints" : {
      "buttons" : [0.33, 0.5, 0.47]
    },
    "properties" : {
      "ntp_background_alignment" : "bottom"
    }
  }

颜色使用 RGB 格式,即 [r, g, b] ;图片路径使用基于主题包根路径的相对路径;properties 定义了图片的位置和 repeat 属性;tints 定义了按钮、框架和后台标签页等某些部分的色调,使用HSL格式,取值范围为0到1的浮点型数据;

omnibox、web_accessible_resources 这两个配置放在下面的案例中演示;

三、自定义页面背景色

  • 重写 popup.html
<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link rel="stylesheet" href="css/popup.css">
</head>

<body>
    <div class="btn-container">
        <button class="button-1"></button>
        <button class="button-2"></button>
        <button class="button-3"></button>
        <button class="button-4"></button>
        <button class="button-5"></button>
        <button class="button-6"></button>
    </div>
    <script src="./js/popup.js"></script>
</body>

</html>
  • 创建 css/popup.css,编写简单的样式,在popup.html 引入;
.btn-container {
    display: flex;
}

button {
    height: 30px;
    width: 30px;
    outline: none;
    margin: 10px;
    border: none;
    border-radius: 2px;
    cursor: pointer;
}

div {
    padding: 10px;
    cursor: pointer;
}

img {
    margin-right: 16px;
    width: 120px;
}

.button-1 {
    background: #FFCCCC;
}

.button-2 {
    background: #FFEE99;
}

.button-3 {
    background: #CCFF99;
}

.button-4 {
    background: #BBFFEE;
}

.button-5 {
    background: #CCCCFF;
}

.button-6 {
    background: #F0BBFF;
}
  • 创建 js/popup.js,编写功能,在popup.html 引入;
const btnColor = ['#FFCCCC', '#FFEE99', '#CCFF99', '#BBFFEE', '#CCCCFF', '#F0BBFF']

const btnArr = document.getElementsByTagName('button')

for (let i = 0, len = btnArr.length; i < len; i++) {
    var btn = btnArr[i];
    btn.onclick = async (event) => {
        const index = event.target.className.split('-')[1]

        // 调用Chrome接口取出当前标签页
        const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

        // 以当前标签页为上下文,执行函数
        chrome.scripting.executeScript({
            target: { tabId: tab.id },
            args: [{ btnColor, index }],  // // 无法访问外面的数据,args 可传递外面的数据 
            function: (event) => {
                document.body.style.backgroundColor = event.btnColor[event.index - 1]
            },
        });

    }
}
  • 修改 manifest.json, permissions 中增加两个权限;
"permissions": [
    "storage",
    "activeTab",
    "scripting"
],
  • 然后重新加载插件,跳转百度,即可随便更改背景色(访问别的网页也可以,如果未生效可自行打开控制台查看,背景色是否添加成功,或者样式权重等问题)

在这里插入图片描述

三、设置页面背景图(web_accessible_resources)

  • 创建 image 文件夹,放入两张图片;
  • 编辑 popup.html
<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link rel="stylesheet" href="css/popup.css">
</head>

<body>
    <div class="btn-container">
        <button class="button-1"></button>
        <button class="button-2"></button>
        <button class="button-3"></button>
        <button class="button-4"></button>
        <button class="button-5"></button>
        <button class="button-6"></button>
    </div>
    <div class="img-container">
        <img id="img1" src="image/ed4ab51c81887ee4b3278addd252932d.png">
        <img id="img2" src="image/64d8c0109f9d8cc997e23b67eb9a2b7d.png">
    </div>
    <script src="./js/popup.js"></script>
</body>

</html>
  • 编辑 popup.js,增加功能代码
// 点击更换背景色
document.getElementById("img1").onclick = async () => {
    var imgurl = chrome.runtime.getURL("image/ed4ab51c81887ee4b3278addd252932d.png");
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
    chrome.scripting.executeScript({
        target: { tabId: tab.id },
        args: [imgurl],
        function: (event) => {
            document.body.style.backgroundAttachment = 'fixed';
            document.body.style.backgroundSize = '100% 100%';
            document.body.style.backgroundImage = 'url(' + event + ')'
        },
    });
}

document.getElementById("img2").onclick = async () => {
    var imgurl = chrome.runtime.getURL("image/64d8c0109f9d8cc997e23b67eb9a2b7d.png");
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
    chrome.scripting.executeScript({
        target: { tabId: tab.id },
        args: [imgurl],
        function: changeBg,
    });
}

function changeBg(event) {
    document.body.style.backgroundAttachment = 'fixed';
    document.body.style.backgroundSize = '100% 100%';
    document.body.style.backgroundImage = 'url(' + event + ')'
}
  • 修改 manifest.json, 配置 web_accessible_resources,否则图片无法访问;
"web_accessible_resources": [
    {
        "resources": [
            "image/*"
        ],
        "matches": [
            "http://*/*",
            "https://*/*"
        ]
    }
]
  • 然后重新加载插件,跳转百度,即可随便设置背景图;
    在这里插入图片描述

四、设置徽章(Badge)

  • 编辑 popup.html
<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link rel="stylesheet" href="css/popup.css">
</head>

<body>
    <div class="btn-container">
        <button class="button-1"></button>
        <button class="button-2"></button>
        <button class="button-3"></button>
        <button class="button-4"></button>
        <button class="button-5"></button>
        <button class="button-6"></button>
    </div>
    <div class="img-container">
        <img id="img1" src="image/ed4ab51c81887ee4b3278addd252932d.png">
        <img id="img2" src="image/64d8c0109f9d8cc997e23b67eb9a2b7d.png">
    </div>
    <div id="badgeText">设置徽章文本</div>
    <div id="badgeBg">设置徽章背景颜色</div>
    <script src="./js/popup.js"></script>
</body>

</html>
  • 编辑 popup.js,增加功能代码
// 设置徽章文本
document.getElementById("badgeText").onclick = function () {
    // 设置徽章文本
    chrome.action.setBadgeText({ "text": '88' });
}

// 设置徽章背景颜色
document.getElementById("badgeBg").onclick = function () {
    // 设置徽章背景颜色
    // color 范围为[0,255]整数构成的结构(必须是整数),用来描述badge的RGBA颜色
    chrome.action.setBadgeBackgroundColor({ color: [153, 96, 230, 2] });
}
  • 重新加载插件,即可看到效果;

在这里插入图片描述

五、桌面通知

  • 通知用户发生了一些重要的事情,桌面通知会显示在浏览器窗口之外;
  • 编辑 popup.html
<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link rel="stylesheet" href="css/popup.css">
</head>

<body>
    <div class="btn-container">
        <button class="button-1"></button>
        <button class="button-2"></button>
        <button class="button-3"></button>
        <button class="button-4"></button>
        <button class="button-5"></button>
        <button class="button-6"></button>
    </div>
    <div class="img-container">
        <img id="img1" src="image/ed4ab51c81887ee4b3278addd252932d.png">
        <img id="img2" src="image/64d8c0109f9d8cc997e23b67eb9a2b7d.png">
    </div>
    <div id="badgeText">设置徽章文本</div>
    <div id="badgeBg">设置徽章背景颜色</div>
    <div id="notify">桌面通知</div>
    <script src="./js/popup.js"></script>
</body>

</html>
  • 编辑 popup.js,增加功能代码
// 桌面通知
document.getElementById("notify").onclick = function () {
    notify()
    setTimeout(function (e) {
        // 清除桌面通知成功
        // 这里的id只要和创建的时候设置id值一样就行了,就可以清理对应id的通知了
        chrome.notifications.clear("id");
    }, 2000);
}

// 桌面通知
// id: 保证每个通知的唯一,这个id是字符串类型
// type: 通知类型,有basic(默认)、image、list、progress
// iconUrl: 图标的url
// imageUrl:"image"类型的通知的图片的URL
// appIconMaskUrl: 应用图标URL的掩码,用以规范URL,这个扩展应该是用不到
// title: 通知主标题
// message: 通知副标题
// contextMessage: 通知的备选内容,
// progress:进度
// buttons: [{title: '按钮1的标题', iconUrl:' icon.png'},{title: '按钮2的标题',iconUrl: 'icon.png'}],  最多两个按钮
// items: [{title: '消息1', message: '消息1'},{title: '消息2', message: '消息2'}], 通知列表,对应type是list时使用,只有title和message两个属性
// eventTime: Date.now() + 2000  通知的时间戳
function notify() {
    chrome.notifications.create("id", {
        type: 'basic',
        title: '桌面通知',
        message: '自定义桌面消息通知 !!!',
        iconUrl: 'icons/icon16.png',
        contextMessage: '2 秒后,清除桌面通知 !!!',
        buttons: [
            {
                title: '按钮标题',
                iconUrl: 'icons/icon16.png'
            }
        ],
        eventTime: Date.now() + 2000
    },
        (id) => console.log('111111111'));
}
  • 修改 manifest.json, permissions 中增加权限;
"permissions": [
    "storage",
    "activeTab",
    "scripting",
    "notifications"
],
  • 重新加载插件,即可看到效果;
    在这里插入图片描述

六、消息通信

  • 编辑 popup.html
<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link rel="stylesheet" href="css/popup.css">
</head>

<body>
    <div class="btn-container">
        <button class="button-1"></button>
        <button class="button-2"></button>
        <button class="button-3"></button>
        <button class="button-4"></button>
        <button class="button-5"></button>
        <button class="button-6"></button>
    </div>
    <div class="img-container">
        <img id="img1" src="image/ed4ab51c81887ee4b3278addd252932d.png">
        <img id="img2" src="image/64d8c0109f9d8cc997e23b67eb9a2b7d.png">
    </div>
    <div id="badgeText">设置徽章文本</div>
    <div id="badgeBg">设置徽章背景颜色</div>
    <div id="notify">桌面通知</div>
    <div id="message">消息通信</div>
    <script src="./js/popup.js"></script>
</body>

</html>
  • 编辑 popup.js,增加发送功能代码,同时接收来自 background.js 的回应;
document.getElementById("message").onclick = function () {
    chrome.runtime.sendMessage({ 'msg': 'Hello' }, function (event) {
        chrome.notifications.create("msg", {
            type: 'basic',
            title: '响应通知',
            message: `收到响应,响应报文: ${event.farewell}`,
            iconUrl: 'icons/icon16.png',
        })
    })
}
  • 编辑 background.js,接收 popup 传递的消息
// chrome.runtime.onMessage.addListener(callback)
// 此处的callback为必选参数,为回调函数。
// callback接收到的参数有三个,分别是message、sender和sendResponse,即消息内容、消息发送者相关信息和相应函数。
// 其中sender对象包含4个属性,分别是tab、id、url和tlsChannelId,tab是发起消息的标签
chrome.runtime.onMessage.addListener(
    function (message, sender, sendResponse) {
        if (message.msg == 'Hello') {
            sendResponse({ farewell: "goodbye" });
        }
    }
);
  • 重新加载插件,即可看到效果;
    在这里插入图片描述

七、自定义右键菜单(添加、更新、删除)

  • chrome.contextMenus 模块用于在 Chrome 的右键菜单中增加自己的菜单项;

    你可以选择针对不同类型的对象(如图片,链接,页面)增加右键菜单项;

    你可以根据需要添加多个右键菜单项。一个扩展里添加的多个右键菜单项会被Chrome自动组合放到对应扩展名称的二级菜单里。

    右键菜单可以出现在任意文档(或文档中的框架)中,;若想控制右键菜单在不同文档中的显示,可以在调用 create(object createProperties, function callback) 和update(object createProperties, function callback) 时指定 documentUrlPatterns;

字段名类型说明
typeoptional enumerated string [“normal”, “checkbox”, “radio”, “separator”]右键菜单项的类型;默认为“normal”
titleoptional string右键菜单项的显示文字;除非为“separator”类型,否则此参数是必须的。如果类型为“selection”,您可以在字符串中使用%s显示选定的文本;例如,如果参数的值为 “Translate ‘%s’ to Pig Latin”,而用户还选中了文本“cool”,那么显示在菜单中的将会是 “Translate ‘cool’ to Pig Latin”
checkedoptional booleanCheckbox或者radio的初始状态:true代表选中,false代表未选中;在给定的radio中只能有一个处于选中状态
contextsoptional array of string [“all”, “page”, “frame”, “selection”, “link”, “editable”, “image”, “video”, “audio”]右键菜单项将会在这个列表指定的上下文类型中显示。默认为“page”
onclickoptional function当菜单项被点击时触发的函数;默认有两个参数,info ( OnClickData ) 右键菜单项被点击时相关的上下文信息,tab ( Tab ) 右键菜单项被点击时,当前标签的详细信息
parentIdoptional integer右键菜单项的父菜单项ID;指定父菜单项将会使此菜单项成为父菜单项的子菜单
documentUrlPatternsoptional array of string这使得右键菜单只在匹配此模式的url页面上生效
targetUrlPatternsoptional array of string类似于documentUrlPatterns,但是您可以针对img/audio/video标签的src属性和anchor标签的href做过滤
enabledoptional boolean启用或者禁用此菜单项,启用为true,禁用为false;默认为true
  • 编辑 popup.html
<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link rel="stylesheet" href="css/popup.css">
</head>

<body>
    <div class="btn-container">
        <button class="button-1"></button>
        <button class="button-2"></button>
        <button class="button-3"></button>
        <button class="button-4"></button>
        <button class="button-5"></button>
        <button class="button-6"></button>
    </div>
    <div class="img-container">
        <img id="img1" src="image/ed4ab51c81887ee4b3278addd252932d.png">
        <img id="img2" src="image/64d8c0109f9d8cc997e23b67eb9a2b7d.png">
    </div>
    <div id="badgeText">设置徽章文本</div>
    <div id="badgeBg">设置徽章背景颜色</div>
    <div id="notify">桌面通知</div>
    <div id="message">消息通信</div>
    <div id="contextMenus">自定义右键菜单</div>
    <script src="./js/popup.js"></script>
</body>

</html>
  • 编辑 popup.js,向 background.js 发送创建菜单的消息,同时接收来自 background.js 的回应;
// 自定义右键菜单
document.getElementById("contextMenus").onclick = function () {
    chrome.runtime.sendMessage({ 'msg': 'contextMenus' }, function (event) {
        chrome.notifications.create("menus", {
            type: 'basic',
            title: '响应通知',
            message: `收到响应,响应报文: ${event.farewell}`,
            iconUrl: 'icons/icon16.png',
        })
    })
}
  • 编辑 background.js,接收消息,创建菜单;
// chrome.runtime.onMessage.addListener(callback)
// 此处的callback为必选参数,为回调函数。
// callback接收到的参数有三个,分别是message、sender和sendResponse,即消息内容、消息发送者相关信息和相应函数。
// 其中sender对象包含4个属性,分别是tab、id、url和tlsChannelId,tab是发起消息的标签
chrome.runtime.onMessage.addListener(
    function (message, sender, sendResponse) {
        if (message.msg == 'Hello') {
            sendResponse({ farewell: "goodbye" });
        } else if (message.msg == 'contextMenus') {
            // 创建自定义右键菜单
            contextMenus()
            sendResponse({ farewell: "菜单创建成功 !!!" });
        }
    }
);


// 自定义右键菜单
function contextMenus() {
    chrome.contextMenus.create({
        title: "自定义右键快捷菜单", //菜单的名称
        id: '01', //一级菜单的id
        contexts: ['page'], // page表示页面右键就会有这个菜单,如果想要当选中文字时才会出现此右键菜单,用:selection
    });

    chrome.contextMenus.create({
        title: '百度', //菜单的名称
        id: '0101',//二级菜单的id
        parentId: '01',//表示父菜单是“右键快捷菜单”
        contexts: ['page'],
    });

    chrome.contextMenus.create({
        title: 'CSDN', //菜单的名称
        id: '0102',
        parentId: '01',//表示父菜单是“右键快捷菜单”
        contexts: ['page'],
    });

    chrome.contextMenus.create({
        title: '自定义选中文字跳转百度搜索', //菜单的名称
        id: '02',
        contexts: ['selection'],
    });

    chrome.contextMenus.onClicked.addListener((info, tab) => {
        if (info.menuItemId == '0101') {
            var createData = {
                url: "https://baidu.com",
                type: "popup",
                top: 200,
                left: 300,
                width: 1300,
                height: 800
            }
            // 创建(打开)一个新的浏览器窗口,可以提供大小、位置或默认 URL 等可选参数
            chrome.windows.create(createData);
        } else if (info.menuItemId == '02') {
            // 选中文字跳转百度检索
            chrome.tabs.create({ url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(info.selectionText) });
        } else if (info.menuItemId == '0102') {
            chrome.tabs.create({ url: 'https://www.csdn.net' });
        }
    })
}
  • 修改 manifest.json, permissions 中增加权限;
"permissions": [
     "storage",
     "activeTab",
     "scripting",
     "notifications",
     "contextMenus"
 ],
  • 重新加载插件,鼠标右击,即可看到效果;

在这里插入图片描述

  • 选中文字,鼠标右击,亦可直接跳转百度检索;

在这里插入图片描述

  • 编辑 popup.html,增加更新、删除功能
<div id="removeContextMenus">删除第一个自定义右键菜单</div>
 <div id="updateContextMenus">更新第二个自定义右键菜单</div>
 <div id="removeAll">删除所有自定义右键菜单</div>
  • 编辑 popup.js
// 移除自定义菜单
document.getElementById("removeAll").onclick = function () {
    chrome.contextMenus.removeAll(() => {
        chrome.notifications.create("removeAll", {
            type: 'basic',
            title: '移除自定义菜单',
            message: '移除自定义菜单 !!!',
            iconUrl: 'icons/icon16.png',
        })
    })
}

// 更新第二个自定义右键菜单
document.getElementById("updateContextMenus").onclick = function () {
    chrome.contextMenus.update('0102',
        {
            type: 'checkbox',
            checked: true,
            title: '我是更新后的菜单',
            parentId: '01',
            contexts: ['page'],

        }, () => {
            chrome.notifications.create("update", {
                type: 'basic',
                title: '更新第二个菜单',
                message: '更新第二个菜单 !!!',
                iconUrl: 'icons/icon16.png',
            })
        })
}

// 移除第一个菜单
document.getElementById("removeContextMenus").onclick = function () {
    chrome.contextMenus.remove('0101', () => {
        chrome.notifications.create("remove", {
            type: 'basic',
            title: '移除第一个菜单',
            message: '移除第一个右键菜单 !!!',
            iconUrl: 'icons/icon16.png',
        })
    })
}

八、Omnibox

  • omnibox 应用程序界面允许向Google Chrome的地址栏注册一个关键字,地址栏也叫 omnibox;

    当用户输入你的扩展关键字,用户开始与你的扩展交互,每个击键都会发送给你的扩展,扩展提供建议作为相应的响应;

  • 编辑 background.js,增加下面的代码;

// 用户在地址栏上输入了一个关键词(在 manifest.json / omnibox 中 keyword)然后按下tab键
// 当检测到特定的关键词与我们事先指定的关键词相匹配时将调用对应的插件

// 当用户按下tab chrome将输入交给插件,然后输入第一个字符之后触发此事件
chrome.omnibox.onInputStarted.addListener(() => {
    console.log("[" + new Date() + "] omnibox event: onInputStarted");
});

// 当用户的输入改变之后
// text 用户的当前输入
// suggest 调用suggest为用户提供搜索建议
chrome.omnibox.onInputChanged.addListener((text, suggest) => {
    console.log("[" + new Date() + "] omnibox event: onInputChanged, user input: " + text);
    // 为用户提供一些搜索建议
    suggest([
        {
            "content": text + "*",
            "description": "是否跳转 baidu 检索" + text + "检索相关内容?"
        },
        {
            "content": text + " abj",
            "description": "是否要查看“" + text + " abj” 有关的内容?"
        },
        {
            "content": text + " aibujn",
            "description": "是否要查看“" + text + " aibujn” 有关的内容?"
        }
    ]);
});

// 按下回车时事件,表示向插件提交了一个搜索
chrome.omnibox.onInputEntered.addListener((text, disposition) => {
    console.log("[" + new Date() + "] omnibox event: onInputEntered, user input: " + text + ", disposition: " + disposition);
    if (text.indexOf('*') != -1) {
        chrome.tabs.create({ url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(text) });
    }
});

// 取消输入时触发的事件,注意使用上下方向键在搜索建议列表中搜搜也会触发此事件
chrome.omnibox.onInputCancelled.addListener(() => {
    console.log("[" + new Date() + "] omnibox event: onInputCancelled");
});

// 当删除了搜索建议时触发的
chrome.omnibox.onDeleteSuggestion.addListener(text => {
    console.log("[" + new Date() + "] omnibox event: onDeleteSuggestion, text: " + text);
});

// 设置默认的搜索建议,会显示在搜索建议列表的第一行位置,content省略使用用户当前输入的text作为content
chrome.omnibox.setDefaultSuggestion({
    "description": "啥也不干,就是随便试试...."
})
  • 修改 manifest.json,增加 omnibox 配置对应的关键词;
"omnibox": {
     "keyword": "aibujin"
 }
  • 重新加载插件,在地址栏输入"aibujin",然后按 tab,即可看到效果;

    参考地址:https://www.cnblogs.com/cc11001100/p/12353361.html

九、浏览器交互

  • 编辑 popup.html
<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <link rel="stylesheet" href="css/popup.css">
</head>

<body>
    <div class="btn-container">
        <button class="button-1"></button>
        <button class="button-2"></button>
        <button class="button-3"></button>
        <button class="button-4"></button>
        <button class="button-5"></button>
        <button class="button-6"></button>
    </div>
    <div class="img-container">
        <img id="img1" src="image/ed4ab51c81887ee4b3278addd252932d.png">
        <img id="img2" src="image/64d8c0109f9d8cc997e23b67eb9a2b7d.png">
    </div>
    <div id="badgeText">设置徽章文本</div>
    <div id="badgeBg">设置徽章背景颜色</div>
    <div id="notify">桌面通知</div>
    <div id="message">消息通信</div>
    <div id="contextMenus">自定义右键菜单</div>
    <div id="removeContextMenus">删除第一个自定义右键菜单</div>
    <div id="updateContextMenus">更新第二个自定义右键菜单</div>
    <div id="removeAll">删除所有自定义右键菜单</div>
    <div id="capture">捕获窗口</div>
    <div id="linkBidu">跳转百度首页</div>
    <div id="openWindows">打开新窗口</div>
    <div id="createPopup">打开自定义窗口</div>
    <div id="windowsMax">窗口最大化</div>
    <div id="windowsMin">窗口最小化</div>
    <div id="currentTab">当前标签打开新网页</div>
    <div id="closeCurrentPage">关闭当前标签页</div>
    <div id="closeCurrentWindow">关闭浏览器</div>
    <script src="./js/popup.js"></script>
</body>

</html>
  • 编辑 popup.js,增加下面的功能代码
// 捕获窗口
// chrome.tabs.captureVisibleTab(integer windowId, object options, function callback)
// windowId ( optional integer )
// 目标窗口,默认值为当前窗口.

// options ( optional object )
// 设置抓取图像参数。设置图像抓取的参数,比如生成的图像的格式。
//     format ( optional enumerated string [“jpeg”, “png”] )
//     生成的图像的格式。默认是jpeg。
//     quality ( optional integer )
//     如果格式是’jpeg’,控制结果图像的质量。此参数对PNG图像无效。当质量降低的时候,抓取的画质会下降,需要存储的字节数也会递减。

// callback ( function ),function(string dataUrl) {...};
//     dataUrl ( string )
//     被抓取标签的可视区域的URL。此URL可能会作为图像的src属性。格式为base64的格式
document.getElementById("capture").onclick = function () {
    chrome.tabs.captureVisibleTab(null, {
        format: "png",
        quality: 100
    }, dataUrl => {
        console.log(dataUrl)
        chrome.tabs.create({ url: dataUrl });
    })
}

// 跳转百度首页
document.getElementById("linkBidu").onclick = function () {
    chrome.tabs.create({ url: 'https://www.baidu.com' });
}

// 打开新窗口
document.getElementById("openWindows").onclick = function () {
    chrome.windows.create({ state: 'maximized' });
}

// 关闭浏览器
document.getElementById("closeCurrentWindow").onclick = function () {
    chrome.windows.getCurrent({}, (currentWindow) => {
        chrome.windows.remove(currentWindow.id);
    });
}

// 最大化窗口
document.getElementById("windowsMax").onclick = function () {
    chrome.windows.getCurrent({}, (currentWindow) => {
        // state: 可选 'minimized', 'maximized' and 'fullscreen' 
        chrome.windows.update(currentWindow.id, { state: 'maximized' });
    });
}

// 最小化窗口
document.getElementById("windowsMin").onclick = function () {
    chrome.windows.getCurrent({}, (currentWindow) => {
        chrome.windows.update(currentWindow.id, { state: 'minimized' });
    });
}

// 当前标签打开新网页
document.getElementById("currentTab").onclick = async () => {
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
    chrome.tabs.update(tab.id, { url: 'https://image.baidu.com/' });
}

// 关闭当前标签页
document.getElementById("closeCurrentPage").onclick = async () => {
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
    chrome.tabs.remove(tab.id);
}

// 创建一个新浏览器窗口
document.getElementById("createPopup").onclick = function () {
    var createData = {
        url: "https://baidu.com",
        type: "popup",
        top: 200,
        left: 300,
        width: 1300,
        height: 800
    }
    // 创建(打开)一个新的浏览器窗口,可以提供大小、位置或默认 URL 等可选参数
    chrome.windows.create(createData);
}
  • 重新加载插件,即可看到效果;

十、根据 url 匹配 popup 窗口能否打开

  • 修改 manifest.json, permissions 中增加权限;
"permissions": [
    "storage",
    "activeTab",
    "scripting",
    "notifications",
    "contextMenus",
    "declarativeContent"
],
  • 修改 background.js, 禁用action, chrome.action.disable(),然后添加自定义规则
chrome.action.disable();

// 删除现有规则,只应用我们的规则
chrome.declarativeContent.onPageChanged.removeRules(undefined, () => {
    // 添加自定义规则
    chrome.declarativeContent.onPageChanged.addRules([
        {
            // 定义规则的条件
            conditions: [
                new chrome.declarativeContent.PageStateMatcher({

                    /**
                     *   下面两个方式根据需要任取一个即可
                     * 
                     *   注意:hostEquals 规则永远不会匹配任何内容,因为根据 the documentation(https://developer.chrome.com/extensions/declarativeContent#type-PageStateMatcher),它将与URL的主机部分进行比较,
                     *   例如简单的www.example.com,因此它不能包含 / 或 *;请注意,chrome.declarativeContent使用自己的过滤系统,
                     *   它不支持 content_scripts 或 webRequest 使用的任何常用匹配模式。
                     */

                    // pageUrl: { hostEquals: 'blog.csdn.net', pathPrefix: '/nav/', schemes: ['https'] },
                    pageUrl: { urlPrefix: 'https://www.baidu.com/' },
                }),
            ],
            // 满足条件时显示操作
            actions: [new chrome.declarativeContent.ShowAction()],
        },
    ]);
});
  • 重新加载插件,即可看到效果;

十一、点击插件跳转至扩展页

  • 目前我们点击插件弹出 popup.html, 现在改为点击插件直接跳转 options.html

  • 修改 background.js, 添加 chrome.action.onClicked.addListener

// 点击插件跳转至 options.html
chrome.action.onClicked.addListener((tab) => {
    chrome.runtime.openOptionsPage();
});
  • 修改 manifest.json, 将 action 改为空对象
"action": {
    // "default_title": "CustChromePlug popup",
    // "default_popup": "popup.html",
    // "default_icon": {
    //     "16": "icons/icon16.png",
    //     "32": "icons/icon32.png",
    //     "48": "icons/icon48.png",
    //     "64": "icons/icon64.png",
    //     "128": "icons/icon128.png"
    // }
},
  • 重新加载插件,访问 “百度” 点击插件(我们在上面添加自定义规则),即可看到效果;

十二、项目地址

项目地址:https://github.com/aibuijn/chrome-plug

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/683047.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JVM基础知识

JVM 一次编译终身运行1.1 JVM和java的体系结构1.1.1 虚拟机与JAVA虚拟机1.1.2 JVM的位置1.1.3 JVM的整体执行流程1.1.4 JAVA代码的执行流程1.1.5 JVM架构模型1.1.6 JVM的生命周期1.1.7 Sun Classic Vm1.1.8 Exact VM1.1.9 Hotspot VM1.1.10 BEA的JRockit1.1.11 IBM的 J91.1.12 …

云渲染是什么?如何挑选云渲染平台

在影视动画、建筑设计、游戏开发等领域&#xff0c;渲染是一个非常重要的环节&#xff0c;它可以将场景、模型、纹理、材质等元素综合起来&#xff0c;生成逼真的图像或视频。然而&#xff0c;渲染也是一个非常耗时和耗能的过程&#xff0c;它需要大量的计算资源和硬件设备&…

Intel base instruction -- Jcc

检查EFLAGS寄存器中一个或多个状态标志&#xff08;CF、of、PF、SF和ZF&#xff09;的状态&#xff0c;如果这些标志处于指定状态&#xff08;条件&#xff09;&#xff0c;则执行跳转到目标操作数指定的目标指令。条件代码&#xff08;cc&#xff09;与每个指令相关联&#xf…

实用干货-汇总篇

_ 实用干货 _ 11.实用干货-基因&基因组知识回顾 (qq.com)22.实用干货—解惑NGS可能引入的错误突变 (qq.com)33.临床肿瘤NGS的常规检测流程 (qq.com)44.实用干货—DNA甲基化相关知识点整理 (qq.com)55.实用干货-NGS的QC质控和突变结果复核 (qq.com)65.实用干货-你可能没…

patch 报错 can‘t find file to patch at input line 4

错误现象&#xff1a; 解决 -p3 patch -p3 < ../speccpu2006-kylinv10-aarch64.patch

问题总结,web自动化测试元素无法操作?shadowDOM节点元素解决......

前言 web自动化遇到shadowDOM你会操作吗&#xff1f; 之前在做web自动化的时候&#xff0c;发现页面上有些元素&#xff0c;在selenium中无法通过xpath来定位&#xff0c;各种原因找了半天都没找到解决方案&#xff0c;最后发现元素在一个叫做shadow-root的节点下面&#xff…

消息通知系统设计

编辑导语&#xff1a;消息通知可以将内容实时送达用户手机页面&#xff0c;但是泛滥的消息通知会引起用户的反感&#xff0c;也违背了这个设计的初衷。如何理解以及设计消息通知&#xff0c;作者作了简单的分享&#xff0c;我们一起来看看吧。 消息通知可以及时地将状态、内容…

开发之路,穷且益坚,不坠青云之志(入门开发者共勉)

引言 2023毕业季&#xff0c;距离笔者毕业已过2年有余。 互联网从业环境由盛转衰&#xff0c;互联网从业者数量剧增&#xff0c;市场竞争异常激烈&#xff0c;原本的利润空间被不断挤压&#xff0c;以至于很多开发者对互联网已经失去了信心与激情。 互联网的市场份额依旧是占…

全志科技T507-H工业核心板规格书(4核ARM Cortex-A53,主频1.416GHz)

1 核心板简介 创龙科技SOM-TLT507是一款基于全志科技T507-H处理器设计的4核ARM Cortex-A53全国产工业核心板&#xff0c;主频高达1.416GHz。核心板CPU、ROM、RAM、电源、晶振等所有元器件均采用国产工业级方案&#xff0c;国产化率100%。 核心板通过邮票孔连接方式引出MIPI C…

6 应用层-6.1【实验】【计算机网络】

6 应用层-6.1【实验】【计算机网络】 前言推荐6 应用层6.1 Web服务与FTP服务配置0 搭建拓扑图1 Web演示2 FTP演示6.1.1实验章节测验 最后 前言 2023-6-25 14:35:53 以下内容源自《创作模板三》 仅供学习交流使用 推荐 4端到端协议-4.3【实验】【计算机网络】 6 应用层 6.…

【Java|多线程与高并发】阻塞队列以及生产者-消费者模型

文章目录 1. 前言2. 阻塞队列3. 实现阻塞队列4. 生产者-消费者模型5. 总结 1. 前言 阻塞队列(BlockingQueue)常用于多线程编程中&#xff0c;可以实现线程之间的同步和协作。它可以用来解决生产者-消费者问题&#xff0c;其中生产者线程将元素插入队列&#xff0c;消费者线程从…

《网络安全0-100》自学误区和陷阱

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员(以编程为基础的学习)再开始学习 我在之前的回答中&#xff0c;我都一再强调不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;而且实际向安全过渡后可用到…

今天面了个腾讯拿 28K 出来的,让我见识到了软件测试的天花板

已经6月底了&#xff0c;你们是在职呢还是待业呢&#xff1f; 今年的春招结束了&#xff0c;而秋招也马上要开始了&#xff0c;很多小伙伴收获不错&#xff0c;拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文&#xff0c;为此咱这里…

如何清除浏览器的 DNS 缓存 (Chrome, Firefox, Safari)

如何清除浏览器的 DNS 缓存 (Chrome, Firefox, Safari) Chrome Chromium Edge Firefox Safari clear DNS Cache, flush DNS cache 请访问原文链接&#xff1a;https://sysin.org/blog/clear-browser-dns-cache/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。…

java版工程管理系统源码,企业级工程项目可视化管理平台

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示1…

Linux 设备驱动程序(四)

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核 Linux 设备驱动程序&#xff08;一&#xff09; Linux 设备驱动程序&#xff08;二&#xff09; Linux 设备驱动程序&#xff08;三&#xff09; Linux 设备驱动程序&#xff08;四&#xff09; Linux设备驱动开发详解 …

大数据应用——spark实验

任务一&#xff1a;比较Spark和hadoop的区别 Spark和Hadoop都是用于分布式计算的框架&#xff0c;但两者有以下区别&#xff1a; 1、处理方式不同。Hadoop是基于MapReduce的&#xff0c;而Spark则是基于内存的分布式计算框架。 2、处理速度不同。因为Hadoop是磁盘读写密集型应用…

代理ip的用途及是否可以降低延迟

在互联网使用中&#xff0c;代理IP是一种被广泛使用的工具&#xff0c;用于隐藏真实IP地址和提供一些额外的功能。人们常常疑惑代理IP是否能够降低延迟&#xff0c;从而提高网络连接的速度和响应时间。下面&#xff0c;就让我们来探讨一下代理ip可以用在那些领域及是不是可以降…

C/S、B/S架构详解,一文带你搞懂

一、CS、BS架构定义 CS架构&#xff08;Client-Server Architecture&#xff09;是一种分布式计算模型&#xff0c;其中客户端和服务器之间通过网络进行通信。在这种架构中&#xff0c;客户端负责向服务器发送请求&#xff0c;并接收服务器返回的响应。服务器则负责处理客户端的…

SpringCloud微服务(二)网关GateWay、Docker、Dockerfile、Linux操作超详细

目录 统一网关GateWay 搭建网关服务的步骤 1、引入依赖 2、编写路由配置及nacos地址 路由断言工厂Route Oredicate Factory 路由过滤器配置 全局过滤器GlobalFilter 过滤器执行顺序 跨域问题处理 Docker ​编辑 Docker与虚拟机 镜像和容器 Docker的安装 启动docke…