2015-09-30 43 views
1

我有一個插件,通過注入CSS文件完全改變網站的外觀。它可以工作,但是在新的外觀出現之前一分鐘,舊的外觀就會出現,因此每次頁面加載時都會導致「閃爍」。新的外觀改變背景顏色等,所以開關非常明顯。 (我只在桌面上注意到這一點,而不是在我的筆記本電腦上,我不知道爲什麼,但其他用戶也報告它,也許更快的計算機使頁面顯示比注入CSS更快)。 CSS注入需要發生,因此注入的CSS是最重要的(如上)。在Chrome擴展中CSS注入過程中閃爍

我已經試過了原因這個問題(代碼後):

  1. 清單:確信CSS是web_accessible_resources
  2. 清單:直接在content_scripts
  3. 在做注射清單:通過javascrip從運行content_scripts
  4. 清單:確保所有內容腳本在document_start運行
  5. 清單:試圖運行從腳本後臺頁面上運行的注射
  6. JS噴油正時:新增的EventListener爲DOMSubtreeModified
  7. JS注射時間:增加了對事件偵聽chrome.webNavigation.onCommitted
  8. JS注射時間:等待document.head/document.body的
  9. JS注入法:的appendChild
  10. JS注入法:chrome.tabs.executeScript()
  11. JS注射編碼:鏈接元件鏈接到CSS文件中擴展
  12. JS注射編碼:直接執行的JavaScript

代碼示例:

清單:

{ 
    "manifest_version": 2, 
    "name": "foo", 
    "short_name": "bar", 
    "description": "baz", 
    "options_page": "options.html", 
    "version": "2.1.1", 
    "homepage_url": "http://google.com/", 
    "permissions": ["storage", "*://google.com/*", "webNavigation", "tabs", "activeTab"], 
    "browser_action": { 
    "default_icon": "icon16.png", 
    "default_title": "title", 
    "default_popup": "popup.html" 
    }, 
    "icons": { 
    "16": "icon16.png", 
    "48": "icon48.png", 
    "128": "icon128.png" 
    }, 
    "content_scripts": [ 
    { 
     "matches": ["*://google.com/*"], 
     "js": ["carbonicEditionScript.js"], 
     "all_frames": true, 
     "run_at": "document_start" 
    } 
    ], 
    "background": { 
    "page": "popup.html" 
    }, 
    "web_accessible_resources": ["carbonicEditionStyle.css"] 
} 

carbonicEditionScript.js

document.addEventListener('DOMSubtreeModified', injectStyle, false); 
function injectStyle(){ 
    document.removeEventListener('DOMSubtreeModified', injectStyle, false); 
    var style = document.createElement('style'); 
    style.setAttribute("id", "CarbonicEditionStyle"); 
    style.setAttribute("class", "CarbonicEditionStyle"); 
    style.setAttribute("type", "text/css"); 
    style.appendChild(document.createTextNode(css)); 
    document.getElementsByTagName("html")[0].appendChild(style); 
} 

carbonicEditionScript 替代的.js

document.addEventListener('DOMSubtreeModified', injectCSS, false); 
function injectCSS(){ 
var style = document.createElement('link'); 
style.rel = 'stylesheet'; 
style.type = 'text/css'; 
style.href = chrome.extension.getURL('carbonicEditionStyle.css'); 
if(document.head){ 
    document.removeEventListener('DOMSubtreeModified', injectCSS, false); 
    (document.head||document.documentElement).appendChild(style); 
}} 

background.js

chrome.webNavigation.onCommitted.addListener(function(o) { 
    chrome.tabs.executeScript(o.tabId, { 
     code: "var css = 'body{background-color: green !important;}'; var style = document.createElement('style'); style.setAttribute('id', 'CarbonicEditionStyle'); style.setAttribute('class', 'CarbonicEditionStyle'); style.setAttribute('type', 'text/css'); style.appendChild(document.createTextNode(css)); document.getElementsByTagName('html')[0].appendChild(style);" 
    }); 
}, { 
    url: [{hostContains: 'google.com'}] 
}); 

有誰知道這是怎麼回事?上述所有解決方案都可以工作,但閃爍仍在發生。

回答

2

Stylish-chrome擴展fixed the flicker只是通過使用webNavigation.onCommited事件,所以你應該已經能夠解決這個問題。但是,您遇到的問題可能是由於您提及web_accessible_resources而異步讀取擴展包中的css代碼所致。在這種情況下,將其緩存在chrome.storage.localsessionStoragelocalStorage中。或者考慮在內容腳本中嵌入CSS。

一些[可能冗餘]注意到您所發佈的代碼:

  1. 不要使用DOMSubtreeModified事件,因爲它是一個),實際上不需要 - (你可以注入元素的網頁解析甚至在)和b)古老/不贊成/慢/不好。

    所以整個內容腳本可能是:

    var style = document.createElement('style'); 
    style.id = "CarbonicEditionStyle"; 
    style.className = "CarbonicEditionStyle"; 
    style.type = "text/css"; 
    style.textContent = "body{background-color: green !important;}"; 
    (document.body || document.head || document.documentElement).appendChild(style); 
    
  2. 使用runAt: "document_start"executeScript因爲默認情況下它是document_idle只有當DOM被加載並解析其通常發生:

    chrome.tabs.executeScript(o.tabId, {runAt: "document_start", code: "......"}); 
    
  3. 考慮通過insertCSS直接注入CSS(並非真正需要消除閃爍,它不會讓您禁用注入的樣式,但爲了完成ESS):

    chrome.tabs.insertCSS(o.tabId, {runAt: "document_start", code: "body{background....."}); 
    
  4. "matches": ["*://google.com/*"],不會匹配www.google.com這是默認使用的,所以應該是"matches": ["*://*.google.com/*"],
  5. google.com不是唯一的領域,也有很多國際域名。
+0

我已經嘗試在內容腳本中嵌入css。將看看本地存儲是否有所作爲。 – user1800592

+0

1.上述代碼不會產生閃爍,但它的插入速度非常快,因此它是第一個要讀取的CSS,因此最不重要的是大部分CSS注入都無用。由於網站已經這樣做了,所以使用!important等來更改注入的CSS是不可能的,我無法控制這一點。注入的CSS應該最後添加/讀取,因此優先。 (1) 4 + 5。看起來合理,我會看看我是否可以得到它,以避免(1) 4 + 5中的問題。更改清單中的網址,這可以忽略 – user1800592

+0

問題1聽起來像是基本上無法解決的問題,除非您使用'webRequest'阻止實際的CSS文件。 – Xan