iis建好的网站套用模板,哔哩哔哩网站开发图片,北京做seo的公司,自己做效果图的网站背景
头疼在国际化功能普遍的前端项目中#xff0c;如果你在处理或者在某一块功能上新增一些需求的时候#xff0c;在没有国际化功能的页面中#xff0c;我们随便复制一些文本#xff0c;然后在vs code中全局搜索#xff0c;很快就可以找到所要更改的代码文件在哪里…背景
头疼在国际化功能普遍的前端项目中如果你在处理或者在某一块功能上新增一些需求的时候在没有国际化功能的页面中我们随便复制一些文本然后在vs code中全局搜索很快就可以找到所要更改的代码文件在哪里但是 众所周知国际化功能中的项目如果你的国际化文件写死在项目中那就可以退场啦所有的文本都是唯一key的映射产物而我们的代码中也只是引用这个唯一的key怎么快速找到这个key成为了让我们头疼的事情
目的
为了节省自己日常开发的时间成本为工作增效哈哈哈哈顺带哈
分析
遇到问题解决问题 灵感来源于谷歌浏览器的翻译插件 可不可以有类似的插件当我选中某一段文本他就会检索出来包含这段文本的一些key或者一个key呢所以解决问题的版本就出来了
好接下来我们有了新的问题怎么开发一个谷歌浏览器的插件多得博主之前有相关经验也不难大家要接受新的事物进入自己的世界直接上一个manifestV3开发文档都准备好那就开始
技术栈
Manifest v3
具备技能前端三座大山。
配置文件 对于谷歌浏览器的插件开发来说manifest.json的配置是至关重要的它是一切的源头相当于我们日常开发项目中的 index.js 入口文件 manifest.json
{name: 插件的名称,description: 插件的描述,version: 0.1,permissions: [contextMenus],background: {service_worker: service_worker.js},content_scripts: [{js: [lucky.js],matches: [https://*.bxingupdate.com/*, https://*.bitvenus.live/*, https://www.bvox.com/*],run_at: document_end,world: MAIN},{js: [func.js],matches: [https://*.bxingupdate.com/*, https://*.bitvenus.live/*, https://www.bvox.com/*],all_frames: true,run_at: document_end}],manifest_version: 3, // 制定manifest开发版本最新是3 host_permissions: [https://*.bxingupdate.com/*, https://*.bitvenus.live/*, https://www.bvox.com/*],web_accessible_resources: [],action: {default_popup: popup.html,default_icon: {16: icons/icon16.png,48: icons/icon16.png,128: icons/icon16.png}},icons: { // 配置的插件图标16: icons/icon16.png,48: icons/icon16.png,128: icons/icon16.png}
}
这里以谷歌浏览器插件 redux devtools为例 上图绿色区域就是manifest中的名称红色部分就是描述左侧图标就是icons配置的
那 action 中的 default_popup 就是我们在使用浏览器扩展的时候 类似这里弹出来的这个弹窗就是popup.html所书写的内容。
以上其他的一些key的含义可自行前往官网去查看且官网上面会有你需要的各种案例。
目录结构 service_worker.js, 也常被称为background.js它的作用是 如此 func.js, 它是content-scripts的一种是当前页面与扩展程序沟通的媒介 lucky.js, 与func.js一样都是content-scripts不过它的特征在于 它是以script脚本直接运行在当前页面的 这样看更清晰一些以下两张图看得出他们所处在不同的加载位置 popup.js, 这个是用于popup.html中的一些脚本书写
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta nameviewport contentwidthdevice-width, initial-scale1.0 /title插件/title/headstyle..../stylebody....script src./popup.js/script/body
/html接下来介绍下以上这个插件中我们需要用到的通信方法
通信
1. conent-script与background之间的通信 content-script怎么给background发送消息呢 使用chrome.runtime.sendMessage api给background发送消息。 background又怎么接收消息 使用chrome.runtime.onMessage.addListener api来接收其他人给他发送的消息包括下面的popup而且这个api的第一个参数是个函数该函数中的第三个参数可以用作消息通信可以发送一些消息给传递给他消息的人 #mermaid-svg-B6jl87noBtVEIEaA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-B6jl87noBtVEIEaA .error-icon{fill:#552222;}#mermaid-svg-B6jl87noBtVEIEaA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-B6jl87noBtVEIEaA .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-B6jl87noBtVEIEaA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-B6jl87noBtVEIEaA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-B6jl87noBtVEIEaA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-B6jl87noBtVEIEaA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-B6jl87noBtVEIEaA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-B6jl87noBtVEIEaA .marker.cross{stroke:#333333;}#mermaid-svg-B6jl87noBtVEIEaA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-B6jl87noBtVEIEaA .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-B6jl87noBtVEIEaA text.actortspan{fill:black;stroke:none;}#mermaid-svg-B6jl87noBtVEIEaA .actor-line{stroke:grey;}#mermaid-svg-B6jl87noBtVEIEaA .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-B6jl87noBtVEIEaA .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-B6jl87noBtVEIEaA #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-B6jl87noBtVEIEaA .sequenceNumber{fill:white;}#mermaid-svg-B6jl87noBtVEIEaA #sequencenumber{fill:#333;}#mermaid-svg-B6jl87noBtVEIEaA #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-B6jl87noBtVEIEaA .messageText{fill:#333;stroke:#333;}#mermaid-svg-B6jl87noBtVEIEaA .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-B6jl87noBtVEIEaA .labelText,#mermaid-svg-B6jl87noBtVEIEaA .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-B6jl87noBtVEIEaA .loopText,#mermaid-svg-B6jl87noBtVEIEaA .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-B6jl87noBtVEIEaA .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-B6jl87noBtVEIEaA .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-B6jl87noBtVEIEaA .noteText,#mermaid-svg-B6jl87noBtVEIEaA .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-B6jl87noBtVEIEaA .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-B6jl87noBtVEIEaA .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-B6jl87noBtVEIEaA .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-B6jl87noBtVEIEaA .actorPopupMenu{position:absolute;}#mermaid-svg-B6jl87noBtVEIEaA .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-B6jl87noBtVEIEaA .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-B6jl87noBtVEIEaA .actor-man circle,#mermaid-svg-B6jl87noBtVEIEaA line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-B6jl87noBtVEIEaA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} content-script background { data: 123 } sendResponse({ data: 456 }) background经过自己的处理, 最终 把相应结果给出. content-script background 那么background又怎么主动发送消息给content-script呢 conent-script又怎么接收的消息 使用 chrome.tabs.sendMessage api主动发消息给content-script而content-script也是通过chrome.runtime.onMessage.addListenerapi来接收消息 #mermaid-svg-ICJp2FlnRkpiUjI6 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ICJp2FlnRkpiUjI6 .error-icon{fill:#552222;}#mermaid-svg-ICJp2FlnRkpiUjI6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ICJp2FlnRkpiUjI6 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-ICJp2FlnRkpiUjI6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ICJp2FlnRkpiUjI6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ICJp2FlnRkpiUjI6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ICJp2FlnRkpiUjI6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ICJp2FlnRkpiUjI6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ICJp2FlnRkpiUjI6 .marker.cross{stroke:#333333;}#mermaid-svg-ICJp2FlnRkpiUjI6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ICJp2FlnRkpiUjI6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ICJp2FlnRkpiUjI6 .cluster-label text{fill:#333;}#mermaid-svg-ICJp2FlnRkpiUjI6 .cluster-label span{color:#333;}#mermaid-svg-ICJp2FlnRkpiUjI6 .label text,#mermaid-svg-ICJp2FlnRkpiUjI6 span{fill:#333;color:#333;}#mermaid-svg-ICJp2FlnRkpiUjI6 .node rect,#mermaid-svg-ICJp2FlnRkpiUjI6 .node circle,#mermaid-svg-ICJp2FlnRkpiUjI6 .node ellipse,#mermaid-svg-ICJp2FlnRkpiUjI6 .node polygon,#mermaid-svg-ICJp2FlnRkpiUjI6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ICJp2FlnRkpiUjI6 .node .label{text-align:center;}#mermaid-svg-ICJp2FlnRkpiUjI6 .node.clickable{cursor:pointer;}#mermaid-svg-ICJp2FlnRkpiUjI6 .arrowheadPath{fill:#333333;}#mermaid-svg-ICJp2FlnRkpiUjI6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ICJp2FlnRkpiUjI6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ICJp2FlnRkpiUjI6 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-ICJp2FlnRkpiUjI6 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-ICJp2FlnRkpiUjI6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ICJp2FlnRkpiUjI6 .cluster text{fill:#333;}#mermaid-svg-ICJp2FlnRkpiUjI6 .cluster span{color:#333;}#mermaid-svg-ICJp2FlnRkpiUjI6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ICJp2FlnRkpiUjI6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 带有两个参数 标签页的id, data background content-script 2. popup和background之间的通信
与content-script类似只不过不能直接与 content script 通信必须通过 background script 作为中介
总结一下通信关系
(1) popup.html
由 popup.js 负责逻辑处理。只能在用户点击扩展图标时显示生命周期短。不能直接与 content script 通信必须通过 background script 作为中介。
(2) content script
运行在网页环境能操作网页 DOM。不能直接访问 background但可以通过 chrome.runtime.sendMessage() 与 background 通信。
(3) background script
持续运行负责处理长期任务、监听事件、管理扩展的状态等。能与 popup 和 content script 进行通信。
主要通信方式
(1) popup ↔ background
单次消息传递
// popup.js
chrome.runtime.sendMessage({ action: getData }, (response) {console.log(收到后台返回的数据:, response);
});// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) {if (request.action getData) {sendResponse({ data: 这是来自后台的数据 });}
});长连接持久连接
// popup.js
let port chrome.runtime.connect({ name: popup });
port.postMessage({ action: ping });port.onMessage.addListener((msg) {console.log(从后台收到:, msg);
});// background.js
chrome.runtime.onConnect.addListener((port) {console.log(popup 连接上了:, port.name);port.onMessage.addListener((msg) {if (msg.action ping) {port.postMessage({ reply: pong });}});
});(2) content script ↔ background
单次消息传递
// content.js
chrome.runtime.sendMessage({ action: fetchData }, (response) {console.log(收到后台返回的数据:, response);
});// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) {if (request.action fetchData) {sendResponse({ data: 这是后台发送给 content script 的数据 });}
});长连接
// content.js
let port chrome.runtime.connect({ name: content_script });
port.postMessage({ action: hello });port.onMessage.addListener((msg) {console.log(收到后台的回复:, msg);
});// background.js
chrome.runtime.onConnect.addListener((port) {console.log(content script 连接上了:, port.name);port.onMessage.addListener((msg) {if (msg.action hello) {port.postMessage({ reply: world });}});
});(3) popup ↔ background ↔ content script间接通信 因为 popup 不能直接访问 content script所以它们必须通过 background script 作为中介。
// popup.js
chrome.runtime.sendMessage({ action: sendToContent, message: 你好content script! });// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) {if (request.action sendToContent) {chrome.tabs.query({ active: true, currentWindow: true }, (tabs) {chrome.tabs.sendMessage(tabs[0].id, { message: request.message });});}
});// content.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) {console.log(收到 popup 传来的消息:, request.message);
});写在最后
如果大家对开发扩展程序感兴趣博主也贡上自己的扩展程序完整代码给大家 国际化助手如果大家看到这里了就给人美心善的博主点个赞赞支持一下吧后续大家有任何相关的问题可以评论区也可以私信博主有应必回在此先感谢大家支持