我正在尝试创建我的第一个Chrome浏览器扩展程序。它应该使用内容脚本来操作指定域的每个页面上的DOM。最初我在style.css
中创建了一个样式规则,只使用了我正在操作的页面中已经存在的选择器 - 这个方法按预期工作。
然后我决定通过添加选项来扩展功能,允许用户从3个与3种不同风格规则相关的状态中进行选择。我添加了scripts.js
来根据所选的选项设置一个类,我将用它作为选择器来应用适当的样式规则。问题是现在我必须等待在我的自定义类应用之前从chrome存储中读取状态,这意味着在我的样式生效之前页面上有默认样式的闪存。
在我的样式加载之前,我应该使用什么方法来防止延迟?
manifest.json (部分)
"content_scripts": [
{
"js": [ "scripts.js" ],
"css": [ "style.css" ],
"matches": [ "https://example.com/*" ]
}
]
scripts.js中
chrome.storage.sync.get("state", function (obj) {
var elem = document.getElementById('targetId');
if (obj.state === 'targetState') {
elem.className += ' myClass';
}
});
的style.css
.myClass {
/* do something */
}
答案 0 :(得分:1)
时尚镀铬扩展solved使用以下步骤解决此问题:
"persistent": true
background page。可以说,它是在此通信场景中可靠地避免FOUC的唯一方法,因为非持久性事件页面需要一些时间来加载。<html>
。在您的情况下,还需要一个额外的步骤:
的manifest.json:
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"js": ["contents.js"]
"matches": ["<all_urls>"],
"run_at": "document_start",
"all_frames": true,
}
],
内容脚本:
var gotData = false;
chrome.runtime.sendMessage({action: 'whatDo'}, doSomething);
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.action == 'doSomething') {
doSomething(msg);
}
});
function doSomething(msg) {
if (gotData || !msg || !msg.data)
return;
gotData = true;
new MutationObserver(onMutation).observe(document, {
childList: true, // report added/removed nodes
subtree: true, // observe any descendant elements
});
function onMutation(mutations, observer) {
// use the insanely fast getElementById instead of enumeration of all added nodes
var elem = document.getElementById('targetId');
if (!elem)
return;
// do something with elem
.............
// disconnect the observer if no longer needed
observer.disconnect();
}
}
后台页面脚本:
var state;
chrome.storage.sync.get({state: true}, function(data) {
state = data.state;
});
chrome.storage.onChanged.addListener(function(changes, namespace) {
if (namespace == 'sync' && 'state' in changes) {
state = changes.state.newValue;
}
});
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.action == 'whatDo') {
sendResponse({action: 'doSomething', data: state});
}
});
chrome.webNavigation.onCommitted.addListener(function(navDetails) {
chrome.tabs.sendMessage(
navDetails.tabId,
{action: 'doSomething', data: state},
{frameId: navDetails.frameId}
);
});
重复消息传递,这是一个不检查消息是否已处理的简单示例:
chrome.webNavigation.onCommitted.addListener(function(navDetails) {
var repetitions = 10;
var delayMs = 10;
send();
function send() {
chrome.tabs.sendMessage(
navDetails.tabId,
{action: 'doSomething', data: state},
{frameId: navDetails.frameId}
);
if (--repetitions)
setTimeout(send, delayMs);
}
});