Using slider to change theme colors

I have several external CSS I can switch among with buttons, but I want to try it with a range slider. I suspect I need something other than “onchange” but I don’t know what.

CSS, with default having ID=blue_css:

  <link rel="stylesheet" href="css/runtime.css" id="blue_css">
  <link rel="alternate stylesheet" media="all" href="css/runtime-blue.css" />
  <link rel="alternate stylesheet" media="all" href="css/runtime-green.css" />

The slider:

<div class="slidecontainer">
  <p>Value: <span id="demo"></span></p>
  <input type="range" min="1" max="3" value="2" class="slider" id="myRange">
</div>

The slider script (which presently doesn’t switch the CSS). The function of the switching script will grab the ID of the default css stylesheet and change the href part to the new stylesheet. This works with buttons onclick, but it doesn’t work here onchange:

<script>
/* from https://www.w3schools.com/howto/howto_js_rangeslider.asp */
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value; // Display the default slider value

/* Update the current slider value (each time you drag the slider handle) 
	if(this.value > 50 && this.value < 101) */
slider.oninput = function() {
	output.innerHTML = this.value;

	if(this.value === 1){
		document.getElementById('blue_button').onchange = function () { 
		document.getElementById('blue_css').href = 'css/runtime-blue.css';
		};
	}

	if(this.value === 2){
		document.getElementById('gray_button').onchange = function () { 
		document.getElementById('blue_css').href = 'css/runtime.css';
		};
	}

	if(this.value === 3){
		document.getElementById('green_button').onchange = function () { 
		document.getElementById('blue_css').href = 'css/runtime-green.css';
		};
	}
}
</script>

Hi there WebSteve,

perhaps this example might help…

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>Untitled document</title>

<!--<link rel="stylesheet" href="screen.css" media="screen">-->

<style media="screen">
body {
    font: normal 1em / 1.5em BlinkMacSystemFont, -apple-system, 'Segoe UI', roboto, helvetica, arial, sans-serif;
    transition: background-color 0.5s ease-in-out;
 }
label {
    display: inline-block;
    padding: 0.75em;
    margin-bottom: 0.5em;
    background-color: #fff;
 }
#myRange{
    display: block;
 }
.effect1 {
   background-color: #f00;
 }
.effect2 {
   background-color: #00f;
 }
.effect3 {
   background-color: #0f0;
 }
</style>

</head>
<body class="effect2">

<label for="myRange">change background</label>
<input type="range" min="1" max="3" value="2" id="myRange">

<script>
(function( d ) {
   'use strict';
   d.getElementById( 'myRange' ).addEventListener( 'change',
      function() {
         switch( this.value ){
            case '1' :
                    d.body.classList.remove( 'effect2' ); 
                    d.body.classList.remove( 'effect3' );
                    d.body.classList.add( 'effect1' );
                    break;
            case '2' :
                    d.body.classList.remove( 'effect1' ); 
                    d.body.classList.remove( 'effect3' );
                    d.body.classList.add( 'effect2' );
                    break;
            case '3' :
                    d.body.classList.remove( 'effect1' ); 
                    d.body.classList.remove( 'effect2' );
                    d.body.classList.add( 'effect3' );
                    break;
          }
      }, false );
}( document ));
</script>

</body>
</html>

coothead

I don’t think this was what he was looking for BUT, this is a much better solution than doing a full on css style sheet switch.

Might be a little cumbersome, since I have about 5 classes to switch, buttons included.

…but no more than your failed attempt. :rofl:

coothead

MUCH better than my attempt!

Seriously, though, what went wrong with it? Was it simply syntax that doesn’t work in that context?

To be honest, I cannot say as I did not test your code. :unhappy:

I would guess, though, that if you change the href of
a link element, then you would need to reload the
page for that change to take effect. :winky:

coothead

I would have guessed the absence of the “input” event.

@WebSteve what’s the difference between an “onchange” and “oninput” ?

That’s easy – I’ve never heard of “oninput” :slight_smile:

1 Like

??? Your posted code had the line

slider.oninput = function() { 

Even if I don’t bother to research unfamiliar code before I use it, I usually do when there’s a problem.

(hint: In other words, always at least scan the code to get a vague feeling for what it’s doing. When you see something that interests you / is unfamiliar, put aside some time to get to know it better.)

1 Like

At a guess it looks like you left the onchange functions in place when they’re not needed.

It should probably look like this.

<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;

slider.oninput = function() {
	output.innerHTML = this.value;
	if(this.value === "1"){
		document.getElementById('blue_css').href = 'css/runtime-blue.css';
	}
	if(this.value === "2"){
		document.getElementById('blue_css').href = 'css/runtime.css';
	}
	if(this.value === "3"){
		document.getElementById('blue_css').href = 'css/runtime-green.css';
	}
}
</script>

That works for me and doesn’t seem to need a reload.

Although alternative stylesheets may be the way to do it properly.

1 Like

I didn’t test either but I have a feeling coot is right since a change of stylesheet paths would need a refresh, but that would just go back to the original settings so not sure how that ever worked?

Supposedly, three CSS files are being loaded, but two are marked as “alternate” so they are not applied. Originally, the functions were activated onclick, one button per stylesheet, and that’s when they were switched. This worked fine. But I wanted a way to have all the stylesheets in a row, even on mobile, without buttons.

Does my example not do what you want?

I’m not really sure what you are getting at when you say “stylesheets in a row”?

The usual way of swapping stylesheets is with alternate stylesheets and changing the attributes as required (usually enabling one and disabling the others). Of course you would need to set cookies if you want the styles persistent over the site once changed. There are many styleswitchers around that will do this.

“stylesheets in a row” s/b “buttons in a row in the form of a slider”

“Does my example not do what you want?” I am tasked with several other things – I’ll get to your example soon!

I am using this online, but the example I was given did not have cookies required.

I see what you mean. I did not need onclick or onchange or oninput because this already detects the input. Thanks.

1 Like

That’s why I was having problems. It works now!
http://www.reedyrace.com/ae/runtime/indexSLIDER.html