0

I am trying to make a chrome extension that changes the css of a website. The css is loaded from pastebin with Ajax. The problem is that the old website is shown before the new css is shown- how can I make it so that only the website with changed css is shown?

Content.js:

var s = document.createElement('style');
s.setAttribute("type", "text/css");
var r;

$('head').ready(function() {
    $.get("https://pastebin.com/raw/css-file", function(r) { 
    s.innerHTML = r;
    document.head.appendChild(s);
    });
});

manifest.json (relevant):

{
"permissions": [
    "https://scratch.mit.edu/*",
    "https://pastebin.com/raw/*"
],

"content_scripts": [
  {
    "matches": [
      "https://scratch.mit.edu/*",
      "http://scratch.mit.edu/*"
    ],
    "js": ["jquery-2.2.2.min.js", "content.js"]
  }
]
}
Melkor
  • 779
  • 1
  • 12
  • 29

1 Answers1

0

One option is to prevent the body from being visible until the new style is loaded, like this:

$('body').hide();

var s = document.createElement('style');
s.setAttribute("type", "text/css");
var r;

$('head').ready(function() {
    $.get("https://pastebin.com/raw/css-file", function(r) { 
        s.innerHTML = r;
        document.head.appendChild(s);
        $('body').show();
    });
});

But this has a side problem in that you don't know for sure how long the $.get() call will take, and if it takes a long time to return, the page will just be blank.

So instead of hiding the body, a better solution might be to temporarily replace the body html, something like this...

// Save the original body, so we can put it back later
var originalBody = $('body').html();

// Replace the body with a please wait message (use whatever you want)
var pleaseWaitBody = '<div style="text-align: center; margin-top: 100px;">Loading, please wait...</div>';
$('body').html(pleaseWaitBody); 

var s = document.createElement('style');
s.setAttribute("type", "text/css");
var r;

$('head').ready(function() {
    $.get("https://pastebin.com/raw/css-file", function(r) { 
        s.innerHTML = r;
        document.head.appendChild(s);

        // Now that the new style is applied, put the original body back
        $('body').html(originalBody);
    });
});

EDIT: The code above won't work for Chrome extensions. However, there is a nother StackOverflow answer that can help. Please see How to hide everything before page load with Chrome Extension

Community
  • 1
  • 1
Brian Pursley
  • 1,098
  • 7
  • 18
  • Doesn't work for me: it loads the original page, flashes blue (This is probably because the background colour is blue), and then loads the page with new css. (this is with the first method) – Melkor Mar 25 '16 at 20:45
  • Where did you put this script? Make sure it is in the head section, and not in the body – Brian Pursley Mar 25 '16 at 20:46
  • This is with a chrome extension, I am using a "content script" to change the css (there isn't a head section). – Melkor Mar 25 '16 at 20:49
  • 1
    Ah yeah, forgot that part (was thinking html page when I wrote the answer). Have you seen this question and the accepted answer? http://stackoverflow.com/questions/24626809/how-to-hide-everything-before-page-load-with-chrome-extension – Brian Pursley Mar 25 '16 at 20:53
  • I managed to miss that answer despite lots of research, it finally works using the second answer. Thanks for the link! – Melkor Mar 25 '16 at 21:01
  • You're welcome. I'm sorry my original answer was off-base, but glad I was able to help you find the eventual answer. – Brian Pursley Mar 25 '16 at 21:09