Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在内容脚本加载到chrome扩展之前,如何避免出现格式错误的内容闪现?_Javascript_Css_Google Chrome_Google Chrome Extension - Fatal编程技术网

Javascript 在内容脚本加载到chrome扩展之前,如何避免出现格式错误的内容闪现?

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存储读取状态,然后才能应用我的自定义类,这意味着在我的样式生

我正在尝试创建我的第一个Chrome浏览器扩展。它应该使用内容脚本在指定域的每个页面上操作DOM。最初,我在
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 */
}
使用以下步骤解决此问题:

  • 将状态缓存在后台页面脚本变量中,并将其发送回内容脚本,内容脚本在开始时请求数据
  • (可选)向内容脚本发送消息,该消息发生在页面开始加载之前,有时甚至在内容脚本运行之前,因此此方法只是一种附加措施。不过,您可以使用后台页面脚本中的setInterval等多次发送同一消息,将其作为唯一的方法
  • 使用
    “持久”:true
    。可以说,在这种通信场景中,这是唯一可以可靠避免的方法,因为非持久性事件页面需要一些时间来加载
  • 声明要在处注入的内容脚本。
    当内容脚本执行时,文档是空的,没有头,没有正文。此时,style extension的功能是样式注入,它只需在
    的正下方添加一个样式元素
  • 在您的情况下,需要额外的步骤:

  • 使用MutationObserver在加载页面时处理该页面(,)
  • manifest.json:

    "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发送。否则,可能还有别的事情发生。您最初是如何打开该页面的?我在答案中添加了一个示例。