chrome.tabs.onUpdated.addListener with delay

6

I've made an extension for Google Chrome that is working. The goal is to change the color of the image pixels on all web pages.

To do this on the pages loaded in the already opened tabs, use the following code (in the background.js file):

function executeScriptsInExistingTabs(){
  chrome.windows.getAll(null, function(wins) {
    for (var j = 0; j < wins.length; ++j) {
      chrome.tabs.getAllInWindow(wins[j].id, function(tabs) {
        for (var i = 0; i < tabs.length; ++i) {
          if (tabs[i].url.indexOf("chrome://") != 0) {
            chrome.tabs.executeScript(tabs[i].id, { file: 'muda_conteudo.js' });
            chrome.browserAction.setIcon({path: "on.png", tabId:tabs[i].id});
          }
        }
      });
     }
   });
 }

To change the color, in the tabs that will be opened after the activation, use the following code (in the background.js file):

chrome.tabs.onUpdated.addListener(function(tabid, info, tab) {
  if (flag){
    if (info.status == "complete") {
       chrome.tabs.executeScript(tabid, {file:"muda_conteudo.js"});
       chrome.browserAction.setIcon({path: "on.png", tabId:tab.id})
    }
  }
});

Everything works perfectly, but when a new tab is opened, the original images are first viewed and only a few microseconds are replaced by the recolored images . I would like to correct that. Anyone have an idea how to do it?

    
asked by anonymous 22.04.2014 / 20:07

1 answer

2

How did bfavaretto mentioned you only work with the images when the site is fully loaded, which make the browser draw the screen again.

What you do is remove all the images while the site loads, as mentioned by Jan Cassio . To do this, you can use various strategies, one of which is to create a script that defines display: none , knowing that not all pages are under your control, you can create a small function in Javascript and execute before the site loads complete.

(function () {
    var imagens = document.querySelectorAll("img");

    for(var i=0; i< imagens.length;i++) {
        imagens[i].style.display = "none";
    }
}());

The problem is that this script only works for the images inside the img tag, in addition it can only hide the images that are already present on the page until the moment of execution, which can be a problem in sites with various elements of images. This solution should not work as well when using Lazy Loading , you would probably have to call the function several times to get the expected result.

A more complete solution can be achieved using CSS , when defining that images should have display: none at the beginning of the body, when loading the pages everything should work normally. And when you finish loading all the content, you re-enable the preview.

For example:

img{
    display: none !important; 
}

Note the use of !important , we use this to ensure the overwriting of image properties already defined within other CSS files. By adding this CSS at the beginning of the body we can guarantee that the images will not be visible.

Now to add our css style we should put it at the top of the page, or inside the head just after the CSS styles of the site itself or at the beginning of the body. According to Google documentation you have to set the following in your manifest file.

"run_at": "document_start"

Once you've done this, just do something like:

function escondeImagens() {
    var conteudo   =    "<style id='fix_imagens'>img{display: none !important;}</style>";
    var head       = document.querySelector("head");
    head.innerHTML = head.innerHTML +  conteudo;
}

It's worth remembering that since your script will run before the head tag exists, if you call the function very early, nothing will happen, so you probably have to make use of setTimeout to ensure that the head already exists. >

To display the images again to select the element with id fix_imagens and remove its contents.

var elem = document.querySelector('#fix_imagens');
elem.innerHTML = '';
    
30.05.2014 / 14:36