14

I'm using this script to allow user to change the background color...

document.onclick = function SetFavColor(e) {
    if (e.target.className == 'AvcGbtn') {
        var favColor = e.target.style.backgroundColor;

        localStorage.setItem('color', favColor);
        document.body.style.backgroundColor = favColor;
        console.log(favColor);
    }
};

document.addEventListener('DOMContentLoaded', function GetFavColor() {
    var favColor = document.body.style.backgroundColor;
    var color = localStorage.getItem('color');

    if (color === '') {
        document.body.style.backgroundColor = favColor;
    } else {
      document.body.style.backgroundColor = color;
    }
});

CSS:

body {
  max-width: 100%;
  min-width: 100%;
  height: 100%;
  font-family: normal;
  font-style: normal;
  font-weight: normal;
  background-color: transparent;
}

.AvcGbtn {
  display: inline-block;
  width: 2em;
  height: 2em;
}

HTML:

<span class="AvcGbtn" style="background: #ffffff; background-size: 100% 100%;" rel="nofollow"></span>      
<span class="AvcGbtn" style="background: #757575; background-size: 100% 100%;" rel="nofollow"></span> 

This is working, but the problem is that it shows the selected color after page is fully loaded. I want to show the color the user selects before the page is loaded.

Example: background color is white, and user selects red. The script shows a white background color before selection, and after the user selects red, the script changes the background color to red. How can I do this?

That is exactly what I'm trying to do with Javascript, example CSS

body:before {
background-color: red;
}
Kalnode
  • 9,386
  • 3
  • 34
  • 62
Leo
  • 314
  • 1
  • 6
  • 27
  • https://stackoverflow.com/questions/885909/how-can-i-execute-javascript-function-before-page-load – Kody R. Dec 18 '18 at 16:03
  • Thanks fro your help, I have see that but do not help me! I need more help on scripts im not that good, Thanks again – Leo Dec 18 '18 at 16:05
  • @Leo I edited your question to hopefully clarify some of what you were asking. If what I suggested is incorrect, please feel free to reject my edit or modify as you see fit. – Tiffany Dec 19 '18 at 01:50

6 Answers6

16

First you can simplify your logic of setting the color like below:

document.addEventListener('DOMContentLoaded', function GetFavColor() {
    var color = localStorage.getItem('color');
    if (color != '') {
        document.body.style.backgroundColor = color;
    }
});

You only need to change the color if there is something stored locally, if not the default color specified in the CSS will be used automatically.

In order to have a fast change you can get rid of any event and put your script within the head tag and instead of targeting the body element you can target the html one and you will have the same result due to background propagation:

<!DOCTYPE html>
<html>
<head>
  <!-- coloration -->
  <style>html {background:red} /*default color*/</style>
  <script>
    var color ="blue" /*localStorage.getItem('color')*/;
    if (color != '') {
      document.documentElement.style.backgroundColor = color;
    }
  </script>
  <!-- -->
</head>
<body>

</body>
</html>

The snippet is changing the code, you need to test locally for more accurate results.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
5

You need to use a different event onreadystatechange. This one fires before the onload. I played around a bit with the functions and set 'orange' as the default for this event and another as the click OFF the buttons as I disabled the cookie stuff that was not in your code. Note; if you want if as fast as the script can run it, do that. (red) as a call (green) as self executing.

I added a console.log so you could see that the colors do change from red to orange to blue based on events (happens fast, see the log times)

(window.getColor=function (c) {
  var favColor = document.body.style.backgroundColor;
  var color = !!c ? c : "#FFFAFF"; //getCookie('color');
  if (color === '') {
    document.body.style.backgroundColor = favColor;
  } else {
    document.body.style.backgroundColor = color;
  }
  console.log(color);
})('green');

function setColor(e) {
  if (e.target.className == 'AvcGbtn') {
    var favColor = e.target.style.backgroundColor;
    //setCookie('color', favColor);
    document.body.style.backgroundColor = favColor;
    console.log(favColor);
  } else {
    getColor("#DAFFFA");
  }
}
document.onreadystatechange = function() {
  if (document.readyState === 'complete') {
    //dom is ready, window.onload fires later
    getColor("orange");
  }
};
document.onclick = setColor;

window.onload = function() {
  getColor('blue');
};
getColor('red');
body {
  max-width: 100%;
  min-width: 100%;
  height: 100%;
  font-family: normal;
  font-style: normal;
  font-weight: normal;
  background-color: transparent;
}

.AvcGbtn {
  display: inline-block;
  width: 2em;
  height: 2em;
}
<span class="AvcGbtn" style="background: #ffffff; background-size: 100% 100%;" rel="nofollow"></span>

<span class="AvcGbtn" style="background: #e8e8e8; background-size: 100% 100%;" rel="nofollow"></span>
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
  • I have edit my question and i have test your code it works, so it load more faster, but i need to add the color on body:before so that is what I want to do with javascript, im nut sure if it is possible or no, thanks for your help – Leo Dec 19 '18 at 01:36
  • i have see your profile and i see you are very good for javascript :) pleas if you have time, then when you have time, took a look at this question https://stackoverflow.com/questions/53754865/javascript-on-checked-box-clone-this-div-on-unchecked-remove-this-div no one solves that! – Leo Dec 19 '18 at 01:40
  • @Leo The only way faster than this that I know of would be to send the information to the server and set the CSS server side in your HMTL before you render your page based upon that data. – Mark Schultheiss Dec 19 '18 at 11:28
5

Don't dismiss the awesome power of old-school Javascript: use document.write effectively in the right places, such as just at the end of the 'head' tag.

<head>
    <link rel="stylesheet" type="text/css" href="..."/>
    <script type="text/javascript">
    (function(){
      var color = localStorage.getItem('color');
      if(typeof(color) === "string" && color != "") {
         document.write("<style type=\"text\/css\">body{background-color:" + color + ";}</style>");
      }
    }());
    </script>
</head>
cjriii
  • 344
  • 1
  • 10
0

Instead of putting your background-color-changing function on window.onload, try putting it in a <script> tag just after the opening <body> tag:

<html>
  ...
  <body>
    <script>
      // This js code will be executed before the rest of the page is loaded
    </script>
    ...
  </body>
</html>
Errorname
  • 2,228
  • 13
  • 23
0

Since inline CSS is processed BEFORE javascript is processed, have you tried simply removing the background color from the inline CSS?

document.onclick = function(e) {
  if (e.target.className == 'AvcGbtn') {
    var favColor = e.target.style.backgroundColor;
    setCookie('color', favColor);
    document.body.style.backgroundColor = favColor;
    console.log(favColor);
  }
};

window.onload = function() {
  var favColor = document.body.style.backgroundColor;
  var color = getCookie('color');
  if (color === '') {
    document.body.style.backgroundColor = favColor;
  } else {
    document.body.style.backgroundColor = color;
  }
};
body {
  max-width: 100%;
  min-width: 100%;
  height: 100%;
  font-family: normal;
  font-style: normal;
  font-weight: normal;
  background-color: transparent;
}
<span class="AvcGbtn" style="background-size: 100% 100%;" rel="nofollow"></span>
<span class="AvcGbtn" style="background-size: 100% 100%;" rel="nofollow"></span>
imvain2
  • 15,480
  • 1
  • 16
  • 21
0

Sometimes all that's needed is to break up the page load into two parts with setTimeout. Example:

<!DOCTYPE html>
<html>
<head>
<script>
//Load page part 1
//setTimeout allows the page to be rendered immediately 
window.onload = function Load1(){
  Load2Timeout = setTimeout(Load2,1);
}
//Load page part 2
//This loop is just simulating a long page load
var f = ""
function Load2() {
  for (var i = 1; i < 50000; i++) {
    f += "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<br>"
  };
  document.body.innerHTML = f
}
</script>
<style>
  body {background-color:Wheat}
</style>
</head>
<body>
  Loading page. Please wait...
</body>
</html>
LesFerch
  • 1,540
  • 2
  • 5
  • 21