Javascript 在内容脚本加载到chrome扩展之前,如何避免出现格式错误的内容闪现?
我正在尝试创建我的第一个Chrome浏览器扩展。它应该使用内容脚本在指定域的每个页面上操作DOM。最初,我在Javascript 在内容脚本加载到chrome扩展之前,如何避免出现格式错误的内容闪现?,javascript,css,google-chrome,google-chrome-extension,Javascript,Css,Google Chrome,Google Chrome Extension,我正在尝试创建我的第一个Chrome浏览器扩展。它应该使用内容脚本在指定域的每个页面上操作DOM。最初,我在style.css中创建了一个样式规则,只使用了我正在操作的页面中已经存在的选择器。该方法按预期工作 然后,我决定通过添加选项来扩展该功能,允许用户从与3种不同样式规则相关的3种状态中进行选择。我添加了scripts.js,以基于所选选项设置一个类,我将使用该选项作为选择器来应用适当的样式规则。问题是,现在我必须等待从chrome存储读取状态,然后才能应用我的自定义类,这意味着在我的样式生
style.css
中创建了一个样式规则,只使用了我正在操作的页面中已经存在的选择器。该方法按预期工作
然后,我决定通过添加选项来扩展该功能,允许用户从与3种不同样式规则相关的3种状态中进行选择。我添加了scripts.js
,以基于所选选项设置一个类,我将使用该选项作为选择器来应用适当的样式规则。问题是,现在我必须等待从chrome存储读取状态,然后才能应用我的自定义类,这意味着在我的样式生效之前,页面上会闪现默认样式
在加载样式之前,我应该使用什么方法来防止延迟
manifest.json(部分)
scripts.js
chrome.storage.sync.get("state", function (obj) {
var elem = document.getElementById('targetId');
if (obj.state === 'targetState') {
elem.className += ' myClass';
}
});
.myClass {
/* do something */
}
style.css
chrome.storage.sync.get("state", function (obj) {
var elem = document.getElementById('targetId');
if (obj.state === 'targetState') {
elem.className += ' myClass';
}
});
.myClass {
/* do something */
}
使用以下步骤解决此问题:
“持久”:true
。可以说,在这种通信场景中,这是唯一可以可靠避免的方法,因为非持久性事件页面需要一些时间来加载当内容脚本执行时,文档是空的,没有头,没有正文。此时,style extension的功能是样式注入,它只需在
的正下方添加一个样式元素"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"js": ["contents.js"]
"matches": ["<all_urls>"],
"run_at": "document_start",
"all_frames": true,
}
],
背景页脚本:
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);
}
});
我试过这个方法,结果和以前一样。doSomething或者我的名字,addClasses直到页面加载后才被调用,所以我仍然有flash。我已经更新了答案。很明显,你没有使用document_start和MutationObserver,我错误地认为你是。我仍然有一半的时间看到flash。它似乎主要出现在初始页面加载时,但当我在站点内的页面之间导航时,它往往会消失。当然比以前好多了,我似乎走上了正确的道路。谢谢通过使用设置间隔(例如10次,间隔10ms)重复发送来自onCommitted的消息(“快速注入模式”),应该可以完全移除FOUC。您也可以尝试从chrome.tabs.onUpdate发送。否则,可能还有别的事情发生。您最初是如何打开该页面的?我在答案中添加了一个示例。