How do I write a chrome extension that applies a content script to a Single Page Application?(如何编写将内容脚本应用于单页面应用程序的Chrome扩展?)
问题描述
我目前正在编写一个扩展,它将把与RegEx模式(特别是德国电话号码的RegEx模式)匹配的每个字符串转换为可点击的链接,方法是在元素的href中添加tel:,并在需要时使用锚标记将其括起来。
在过去的三天里,我一直在努力让我们公司用于他们联系人的One Single Page App正常工作。但每当我将我的扩展加载到浏览器中,然后重新启动浏览器时,它一开始并不应用我的内容脚本。访问页面后,我首先需要刷新页面。
我正在使用以下文件:
清单.json:
{
"name": "testExtension",
"short_name": "testExtension",
"version": "1.0.0",
"manifest_version": 2,
"description": "Replace telephone numbers with clickable links.",
"author": "Ngelus",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"browser_action": {
"default_icon": "icons/icon48.png",
"default_title": "testExtension"
},
"default_locale": "en",
"permissions": [
"tabs",
"activeTab",
"<all_urls>",
"*://*.examplecontactsapp.de/*",
"storage",
"webRequest",
"webNavigation"
],
"content_scripts": [
{
"matches": [
"*://web.examplecontactsapp.de/contacts",
"*://web.examplecontactsapp.de/contacts*"
],
"js": ["src/inject/contentscript.js"]
}
],
"background": {
"scripts": ["src/bg/background.js"],
"persistent": true
}
}
后台.js:
let currentUrl = '';
let tabId;
chrome.webRequest.onCompleted.addListener(
function (details) {
const parsedUrl = new URL(details.url);
if (currentUrl && currentUrl.indexOf(parsedUrl.pathname) > -1 && tabId) {
chrome.tabs.sendMessage(tabId, { type: "pageRendered" });
}
},
{ urls: ['*://web.examplecontactsapp.de/contacts*'] }
);
chrome.webNavigation.onHistoryStateUpdated.addListener(
(details) => {
tabId = details.tabId;
currentUrl = details.url;
},
{
url: [
{
hostSuffix: 'examplecontactsapp.de',
},
],
}
);
ContScript.js:
var readyStateCheckInterval = setInterval(function () {
if (!location.href.startsWith('https://web.examplecontactsapp.de/contacts')) return;
if (document.readyState === 'complete') {
clearInterval(readyStateCheckInterval);
console.log(
`[---testExtension---]: replacing all telephone numbers with clickable links...`
);
replaceNumbersWithLinks();
}
}, 10);
chrome.runtime.onMessage.addListener(function (request) {
if (request && request.type === 'pageRendered') {
const readyStateCheckInterval = setInterval(function () {
if (document.readyState === 'complete') {
clearInterval(readyStateCheckInterval);
console.log(
`[---testExtension---]: replacing all telephone numbers with clickable links...`
);
replaceNumbersWithLinks();
}
}, 10);
}
});
function replaceNumbersWithLinks() {
document
.querySelectorAll(
'body > main > div.page-content > div > table > tbody > tr > td > p > a'
)
.forEach((a) => {
var b = a.innerText.replaceAll(' ', '').trim();
a.removeAttribute('data-phonenumber');
if (b != '') a.href = 'tel:' + b;
});
}
这样做的正确方式是什么? 如何在我每次访问该单页面应用程序时使其工作?
提前感谢大家。
推荐答案
使matches
匹配清单中的整个站点.json:
{
"content_scripts": [
{
"matches": [
"*://web.examplecontactsapp.de/*"
],
"js": ["src/inject/contentscript.js"]
}
],
使用MutationWatch,并使用中等速度的querySelector检查Conentscript.js中每个突变的选择器,然后继续执行速度较慢的querySelectorAll on Success:
const SEL = 'a[data-phonenumber]';
const mo = new MutationObserver(onMutation);
observe();
function onMutation() {
if (document.querySelector(SEL)) {
mo.disconnect();
replaceNumbersWithLinks();
observe();
}
}
function observe() {
mo.observe(document, {
subtree: true,
childList: true,
});
}
function replaceNumbersWithLinks() {
document.querySelectorAll(SEL).forEach((a) => {
a.removeAttribute('data-phonenumber');
const b = a.textContent.replaceAll(' ', '').trim();
if (b) a.href = 'tel:' + b;
});
}
这篇关于如何编写将内容脚本应用于单页面应用程序的Chrome扩展?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何编写将内容脚本应用于单页面应用程序的Chrome扩展?
基础教程推荐
- Karma-Jasmine:如何正确监视 Modal? 2022-01-01
- 在 JS 中获取客户端时区(不是 GMT 偏移量) 2022-01-01
- 角度Apollo设置WatchQuery结果为可用变量 2022-01-01
- 动态更新多个选择框 2022-01-01
- 响应更改 div 大小保持纵横比 2022-01-01
- 当用户滚动离开时如何暂停 youtube 嵌入 2022-01-01
- 有没有办法使用OpenLayers更改OpenStreetMap中某些要素 2022-09-06
- 我什么时候应该在导入时使用方括号 2022-01-01
- 在for循环中使用setTimeout 2022-01-01
- 悬停时滑动输入并停留几秒钟 2022-01-01