先讲一下需求吧,业务方每天需要将同一个value 比如 123
根据对应的keyName 比如PlacementID 复制到对应的input标签内
这里有几百个input 所以需要 【重复操作】 且 【繁琐耗时】 所以就想开发一个插件 来解决这个痛点
首先先将谷歌插件的灵魂文件创建好
{
"name": "广告来源表单插件",
"version": "1.0",
"description": "广告来源表单插件",
"manifest_version": 2,
"background": {
"page": "js/background.js"
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"js/jquery.min.js",
"js/content.js"
],
"css": [
"css/content.css"
]
}
],
"permissions": [
"declarativeContent",
"storage",
"activeTab",
"tabs",
"http://*/*"
],
"page_action": {
"default_popup": "html/popup.html",
}
}
- 坑一: 我无论左键还是右键点击插件的时候popup.html里我写的页面怎么不显示呢?
仔细查看发现是对谷歌的配置还是不太熟悉的关系
page_action
指的是只有当某些特定页面打开才显示的图标,和browserAction
最大的区别是一个始终都显示,一个只在特定情况才显示。
修改后的manifest.json
文件
{
"name": "广告来源表单插件",
"version": "1.0",
"description": "广告来源表单插件",
"manifest_version": 2,
"background": {
"page": "js/background.js"
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"js/jquery.min.js",
"js/content.js"
],
"css": [
"css/content.css"
]
}
],
"permissions": [
"declarativeContent",
"storage",
"activeTab",
"tabs",
"http://*/*"
],
"browser_action": {
"default_popup": "html/popup.html"
}
}
- 坑二:完善了popup页面写了一个按钮在按钮上绑定了对应的点击事件,审查发现事件并未执行,这又是为啥0.0?
翻阅资料发现
- 首先Chrome扩展程序不允许您使用内联JavaScript,所以你的js部分要写在一个外部的js文件中,一般叫做popup.js。
- 想要使click事件生效,我们需要监听在执行事件之前,页面已经加载完成
- 我这里因为需要和当前页面通信也就是【content.js】传递信息,我就这样写了
// popup.js
// 获取对应keyName 及 value
let btn = document.getElementById("syncBtn")
btn.onclick = function (e) {
let keyName = document.getElementById("keyName").value;
let value = document.getElementById("value").value;
tabs(keyName, value);
}
// 去链接,对应的tab标签页面
async function tabs(...arg) {
const tabId = await getCurrentTabId();
console.log('tabId',tabId)
const connect = chrome.tabs.connect(tabId, { name: 'popup' }); // 和指定tabID建立链接,并设置信号名字
// 发送信息
connect.postMessage(arg);
// 接受返回信息
connect.onMessage.addListener(mess => {
console.log(mess)
})
};
// 获取当前 tab ID
function getCurrentTabId() {
return new Promise((resolve, reject) => {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
resolve(tabs.length ? tabs[0].id : null)
});
})
};
// content.js
// 监听链接
chrome.runtime.onConnect.addListener(res => {
if (res.name == "popup") {
res.onMessage.addListener(mes => {
console.log('🥓: popup.js receive', mes);
});
}
3.坑三:单纯的给input赋值了没用,页面内的校验逻辑无法通过,必须模拟人工真实输入的情形
这里我还试了先触发input的focus事件再去赋值都行不通,于是查了下如何触发input绑定的事件才得到了完美的解决,大佬原文 zhuanlan.zhihu.com/p/356661173
// 获取label标签对应父元素的兄弟元素 input
const element = $(v).parent().siblings()[0] //这里获取到了input
var evt = new InputEvent('input', {
inputType: 'insertText',
data: value,
dataTransfer: null,
isComposing: false
});
element.value = value
// 执行input上绑定的事件
element.dispatchEvent(evt)
虽然一路上磕磕绊绊,但最终实现了功能,让业务方从1个小时重复复制粘贴变成了短短2分钟就能搞定的事情,心里还是蛮高兴的,以后希望大家遇到类似的需求能少走一些弯路。