我正在尝试创建我的第一个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 */
}
"persistent": true
背景页面。可以说,这是在这种通信情况下可靠地避免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);
}
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句