Comparing RGB colors in JavaScript - javascript

I'm trying to compare two RGB colors in a guessing game. There are 6 squares with 6 different colors. When the user clicks on the color that matches pickedColor, the result should be 'Correct!'. But I never get that result.
This is my code:
var colors = [
"rgb(255,0,0)",
"rgb(255,255,0)",
"rgb(0,255,0)",
"rgb(0,255,255)",
"rgb(0,0,255)",
"rgb(255,0,255)"
];
var squares = document.querySelectorAll(".square");
var pickedColor = colors[3];
var colorDisplay = document.getElementById("colorDisplay");
colorDisplay.textContent = pickedColor;
for (var i = 0; i < squares.length; i++) {
//add initinal colors to squares
squares[i].style.background = colors[i];
//add the click listener to the squares
squares[i].addEventListener("click", function () {
var clickedColor = this.style.background;
if (clickedColor === pickedColor) alert("Correct!");
else alert("Incorrect!");
});
}

Ok so I set up an example here and it looks like the problem is that your initial set of colours don't have spaces between the commas:
var colors = [
"rgb(255,0,0)",
"rgb(255,255,0)",
"rgb(0,255,0)",
"rgb(0,255,255)",
"rgb(0,0,255)",
"rgb(255,0,255)"
];
clickedColor has no spaces and the pickedColor does, so changing this to:
var colors = [
"rgb(255, 0, 0)",
"rgb(255, 255, 0)",
"rgb(0, 255, 0)",
"rgb(0, 255, 255)",
"rgb(0, 0, 255)",
"rgb(255, 0, 255)"
];
Should do the trick.

The trouble is that the color expression 'rgb(0,255,255)' is formatted differently by the browser. In the test clickedColor === pickedColor, you're comparing two strings that no longer look the same even if they represent the same color.
Different browsers can represent an RGB color in different ways, so it's unsafe to pick a particular format. A better approach is to extract the color components from the strings and compare the component values one by one, as in the code below.
function rgbExtract(s) {
var match = /^\s*rgb\(\s*(\d+),\s*(\d+),\s*(\d+)\)\s*$/.exec(s);
if (match === null) {
return null;
}
return { r: parseInt(match[1], 10),
g: parseInt(match[2], 10),
b: parseInt(match[3], 10) };
}
function rgbMatches(sText, tText) {
var sColor = rgbExtract(sText),
tColor = rgbExtract(tText);
if (sColor === null || tColor === null) {
return false;
}
var componentNames = [ 'r', 'g', 'b' ];
for (var i = 0; i < componentNames.length; ++i) {
var name = componentNames[i];
if (sColor[name] != tColor[name]) {
return false;
}
}
return true;
}
The rgbMatches function is demonstrated in the following snippet. You'll see that you can now click on the square with the correct color and you'll get the appropriate message even though the underlying RGB strings are formatted differently.
var colors = [
"rgb(255,0,0)",
"rgb(255,255,0)",
"rgb(0,255,0)",
"rgb(0,255,255)",
"rgb(0,0,255)",
"rgb(255,0,255)"
];
var squares = document.querySelectorAll(".square");
var pickedColor = colors[3];
var colorDisplay = document.getElementById("colorDisplay");
colorDisplay.textContent = pickedColor;
function message(s) {
document.getElementById('messageContainer').innerHTML = s;
}
function rgbExtract(s) {
var match = /^\s*rgb\(\s*(\d+),\s*(\d+),\s*(\d+)\)\s*$/.exec(s);
if (match === null) {
return null;
}
return { r: parseInt(match[1], 10),
g: parseInt(match[2], 10),
b: parseInt(match[3], 10) };
}
function rgbMatches(sText, tText) {
var sColor = rgbExtract(sText),
tColor = rgbExtract(tText);
if (sColor === null || tColor === null) {
return false;
}
var componentNames = [ 'r', 'g', 'b' ];
for (var i = 0; i < componentNames.length; ++i) {
var name = componentNames[i];
if (sColor[name] != tColor[name]) {
return false;
}
}
return true;
}
for (var i = 0; i < squares.length; ++i) {
var square = squares[i];
square.style.background = colors[i];
square.addEventListener("click", function () {
var clickedColor = this.style.background;
if (rgbMatches(clickedColor, pickedColor)) {
message('Correct! ' + clickedColor + ' matches ' + pickedColor);
} else {
message('Incorrect. ' + clickedColor + ' doesn\'t match ' + pickedColor);
}
});
}
body {
font-family: sans-serif;
}
.square {
display: inline-block;
margin: 5px;
width: 50px;
height: 50px;
border: 1px solid #888;
cursor: pointer;
}
.output {
margin: 10px 5px;
}
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="output" id="colorDisplay"></div>
<div class="output" id="messageContainer"></div>

I would be wary of comparing two rgb strings like this. Different browsers may store style background colors differently (as you have already discovered).
I would suggest writing a custom comparison function which parses two rgb strings and compares them.
Or you could convert them to hex color values and compare those instead.

Do not trust the color returned by the browser. Different browsers will use different formats.
Instead, use classes or data-* attributes to set the color, and check that:
var colors = ["red", "yellow", "lime", "cyan", "blue", "fuchsia"],
squares = document.querySelectorAll(".square"),
pickedColor = colors[Math.floor(Math.random()*colors.length)],
message = document.getElementById("messageContainer");
document.getElementById("colorDisplay").textContent = pickedColor;
for (var i = 0; i < squares.length; ++i) {
squares[i].setAttribute('data-color', colors[i]);
squares[i].addEventListener("click", function () {
var clickedColor = this.getAttribute('data-color');
message.textContent = clickedColor === pickedColor
? "Correct!" : "Incorrect!";
});
}
.square {
display: inline-block;
margin: 5px;
width: 50px;
height: 50px;
border: 1px solid #888;
cursor: pointer;
}
.output {
margin: 10px 5px;
}
[data-color=red] { background: rgb(255,0,0) }
[data-color=yellow] { background: rgb(255,255,0) }
[data-color=lime] { background: rgb(0,255,0) }
[data-color=cyan] { background: rgb(0,255,255) }
[data-color=blue] { background: rgb(0,0,255) }
[data-color=fuchsia] { background: rgb(255,0,255) }
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="output" id="colorDisplay"></div>
<div class="output" id="messageContainer"></div>

Related

How to change all :root variables with one function

Similar question : But can't able to get answer
Can be answer to this question : But has to split on each :
If possible to get all variable in one function and change each values
If there are 2-4 variable than easy to change but when that change to 10 or more
var root = document.querySelector(':root');
function func() {
root.style.setProperty('--r', 'brown');
root.style.setProperty('--b', 'lightblue');
root.style.setProperty('--g', 'lightgreen');
}
:root {
--r: red;
--b: blue;
--g: green;
}
.text1 {
color: var(--r)
}
.text2 {
color: var(--b)
}
.text3 {
color: var(--g)
}
<div class="text1">Hello</div>
<div class="text2">Bye</div>
<div class="text3">World</div>
<button onclick="func()">Change</button>
Is there a way to automatic(dynamically) get all the variables without writing each variable while values array is self entered
var root = document.querySelector(':root');
var roots = getComputedStyle(root);
var re = roots.getPropertyValue('--r')
var bl = roots.getPropertyValue('--b')
var gr = roots.getPropertyValue('--g')
function func() {
root.style.setProperty('--r', 'brown');
root.style.setProperty('--b', 'lightblue');
root.style.setProperty('--g', 'lightgreen');
}
function func2() {
root.style.setProperty('--r', re);
root.style.setProperty('--b', bl);
root.style.setProperty('--g', gr);
}
:root {
--r: red;
--b: blue;
--g: green;
}
.text1 {
color: var(--r)
}
.text2 {
color: var(--b)
}
.text3 {
color: var(--g)
}
<div class="text1">Hello</div>
<div class="text2">Bye</div>
<div class="text3">World</div>
<button onclick="func()">Change</button>
<button onclick="func2()">Orignal</button>
But when getting back to original values then each value is entered by separate variable and for each it is defined .
Is there a way to have a approach which takes original values and variables in separate array automatically.
Thanks for help in advance
I understand you want to first read all the declared variables from the css and store them, so they might be resetted after applying new values?
This code will do this, given that there's just one ':root' declaration in one stylesheet (easily complemented in case 'splitted' declaration in more places needed)
let variableLookup = {
'--r': {
newValue: 'teal'
},
'--b': {
newValue: 'orange'
},
'--g': {
newValue: 'purple'
}
}
var root = document.querySelector(':root');
function setNewColors() {
const cssText = [...document.styleSheets]
.map(styleSheet => [...styleSheet.cssRules]
.filter(CSSStyleRule => CSSStyleRule.selectorText === ':root'))
.flat()[0].cssText
// cssText = ':root { --r: red; --b: blue; --g: green; }'
cssText.match(/{(.*)}/)[1].trim()
.split(';')
.filter(Boolean)
.forEach(declaration => {
const [variable, oldValue] = declaration.split(':').map(str => str.trim())
let entry = variableLookup[variable]
if (entry) entry.oldValue = oldValue
})
console.log('variableLookup >>', variableLookup)
Object.entries(variableLookup).forEach(([variable, {newValue}]) => {
root.style.setProperty(variable, newValue);
})
}
function resetColors() {
Object.entries(variableLookup).forEach(([variable, {oldValue}]) => {
if (oldValue) root.style.setProperty(variable, oldValue)
})
}
:root {
--r: red;
--b: blue;
--g: green;
}
.text1 {
color: var(--r)
}
.text2 {
color: var(--b)
}
.text3 {
color: var(--g)
}
:root {
--c: magenta;
}
<div class="text1">Hello</div>
<div class="text2">Bye</div>
<div class="text3">World</div>
<button onclick="setNewColors()">Change to new colors</button>
<button onclick="resetColors()">Reset old colors</button>
Since the OP is interested in a version without using .split() these could be replaced by using a regex and .match()
const declarations = '--r: red; --b: blue; --g: green;'
const regex1 = /^[\w-:\s]+(?=;)|(?<=;)[\w-:\s]+/g
const declarationsArr = declarations.match(regex1)
console.log(declarationsArr) // ["--r: red", " --b: blue", " --g: green"]
const regex2 = /[\w-]+(?=:)|(?<=:\s)[\w-]+/g
const declarationsSplit = declarationsArr.map(d => d.match(regex2))
console.log(declarationsSplit) // [["--r", "red"], ["--b", "blue"], ["--g", "green"]]
One method can be entering all variables and values in different arrays and fetching values from them . Where variables = values which need to be equal have same index number
var root = document.querySelector(':root');
variable = ['--r', '--b', '--g'];
values = ['violet', 'lightblue', 'lightgreen']
function func() {
for (let i = 0; i < 3; i++)
root.style.setProperty(variable[i], values[i]);
}
:root {
--r: red;
--b: blue;
--g: green;
}
.text1 {
color: var(--r)
}
.text2 {
color: var(--b)
}
.text3 {
color: var(--g)
}
<div class="text1">Hello</div>
<div class="text2">Bye</div>
<div class="text3">World</div>
<button onclick="func()">Change</button>
const root = document.documentElement;
function changeVariables(...values) {
const variables = ["--r", "--g", "--b"];
for (const variable of variables) {
root.style.setProperty(variable, values[variable.indexof(variables)]);
}
}
//Simply execute function like this
changeVariables("#000", "#808080", "#FF0000");
setting new-colors you want to change
backup original-colors
Try the example bellow
var root = document.querySelector(':root');
var $divEle = $("div[class^='text']"); // get all element with class starting with 'text'
var arrCssVar = ['--r', '--b','--g'];
var backupOrgColor= {}
var newColor = {'--r':'brown', '--b':'lightblue', '--g':'lightgreen'}; // ordering color what you want to change
// backup original colors
$divEle.map(function(i, v) {
if(i < arrCssVar.length){
var compStyle = getComputedStyle(this);
// setting key/value pair to Obj
backupOrgColor[arrCssVar[i]] = compStyle.getPropertyValue(arrCssVar[i]);
}
});
// change color
function setNewColors() {
arrCssVar.map(function (key, value) {
//console.log(key + ": key :change: value : "+ newColor[key]);
root.style.setProperty(key, newColor[key]);
});
}
// reset original color
function resetColors() {
arrCssVar.map(function (key, value) {
//console.log(key + ": key :: value : "+ backupOrgColor[key]);
root.style.setProperty(key, backupOrgColor[key]);
});
}
:root {
--r: red;
--b: blue;
--g: green;
}
.text1 {
color: var(--r)
}
.text2 {
color: var(--b)
}
.text3 {
color: var(--g)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text1">Hello</div>
<div class="text2">Bye</div>
<div class="text3">World</div>
<button onclick="setNewColors()">Change</button>
<button onclick="resetColors()">Orignal</button>
Try this example.
Initialize two arrays, one is empty for the current colors form the css and second for a new colors.
Need to define how many variables, then get them and put in an empty array.
Create two functions with loops, in the first we assign the new colors for variables, in the second reset.
const root = document.body;
// Colors arrays
const cssVarColors = [];
const newColors = ['brown', 'lightblue', 'lightgreen'];
// Create an array of variable colors from css.
const cssRootArray = document.styleSheets[0].cssRules;
for (const i of cssRootArray) {
// Check, if :root in the css.
if (i.selectorText.includes('root')) {
const rootArrayLength = i.style.length;
for (let j = 0; j < rootArrayLength; j++) {
const key = i.style[j];
// Create object { key/variable : value/color }
const value = getComputedStyle(root).getPropertyValue(key);
cssVarColors.push({[key]: value});
}
}
}
// We change colors, with variable keys and indexes.
function changeColor() {
for (const i in cssVarColors) {
const key = Object.keys(cssVarColors[i]);
// Check, if newColor array don't have a color.
if (!newColors[i]) {
return;
}
root.style.setProperty(key, newColors[i]);
}
variables();
}
change.addEventListener('click', changeColor);
const root = document.body;
// Colors arrays
const cssVarColors = [];
const newColors = ['brown', 'lightblue', 'lightgreen'];
// Create an array of colors from a css variables file.
const cssRootArray = document.styleSheets[0].cssRules;
for (const i of cssRootArray) {
// Check, if :root in the css.
if (i.selectorText.includes('root')) {
const rootArrayLength = i.style.length;
for (let j = 0; j < rootArrayLength; j++) {
const key = i.style[j];
// Create object { key/variable : value/color }
const value = getComputedStyle(root).getPropertyValue(key);
cssVarColors.push({
[key]: value,
});
}
}
}
// We change colors, with variable keys and indexes.
function changeColor() {
for (const i in cssVarColors) {
const key = Object.keys(cssVarColors[i]);
// Check, if newColor array don't have a color.
if (!newColors[i]) {
return;
}
root.style.setProperty(key, newColors[i]);
}
variables();
}
// Can't separate in loop by [key, value],
// because key has a specific value.
function resetColor() {
for (const i in cssVarColors) {
if (!newColors[i]) {
return;
}
const key = Object.keys(cssVarColors[i]);
const value = Object.values(cssVarColors[i]);
root.style.setProperty(key, value);
}
variables();
}
// Change button
change.addEventListener('click', changeColor);
// Reset button
reset.addEventListener('click', resetColor);
// extra for view
cssVarColors.forEach(clr => {
const el = document.createElement('span');
el.textContent = JSON.stringify(clr);
document.getElementById('variables').appendChild(el);
});
:root {
--r: red;
--b: blue;
--g: green;
--m: magenta;
--black: black;
}
.text1 {
color: var(--r);
}
.text2 {
color: var(--b);
}
.text3 {
color: var(--g);
}
/* Extra style */
body {
display: grid;
grid-template-columns: 50px 150px;
grid-template-rows: auto;
}
section {
grid-column: 1;
}
#variables {
grid-column: 2;
display: flex;
flex-direction: column;
}
span:nth-of-type(1) {
border: 5px solid var(--r);
}
span:nth-of-type(2) {
border: 5px solid var(--b);
}
span:nth-of-type(3) {
border: 5px solid var(--g);
}
span:nth-of-type(4) {
border: 5px solid var(--m);
}
span:nth-of-type(5) {
border: 5px solid var(--black);
}
<section>
<div class="text1">Hello</div>
<div class="text2">Bye</div>
<div class="text3">World</div>
</section>
<div id="variables"></div>
<button id="change">Change</button>
<button id="reset">Reset</button>

Indexing HTML div classes in JavaScript

I am trying to compare two values of different div classes using the data attribute. I have multiple div classes like these two, all with different data-vale:
<div class="card" data-value=38>
<img class ="front-face" src= "PNG/QH.png"/>
</div>
<div class="card" data-value=39>
<img class ="front-face" src= "PNG/KH.png"/>
</div>
Every div class will also receive a unique order using cards.style.order
In a JS function the user will select two cards (firstCard,secondCard) and the function should check if the value of firstCard is one greater than the value of the card with order 1 more than secondCard.
Here is the code I have been trying to use:
const cards = document.querySelectorAll('.card');
if(firstCard.dataset.value === cards[cards.indexOf(secondCard)-1].dataset.value)
cards is an array housing all of my div classes. One of the errors I received told my that indexOf is not a usable function here. I think this may be because the div classes are not actually part of an array and I need a different method to find the 'value of' something rather than the 'index of'.
For example, if a row of cards goes 2D,7S,9D,8H,3D, the user can click 3D for firstCard and 7S for secondCard. The function will verify that the value of 3D is one greater than 2D and will swap the positions of 3D and 7S.
I made my little snippet with auto-generating squares that can be moved as you suggested. You might check it out. If something is not okay, you might point it out, maybe I forgot something.
let cardsArray = [{
"value": 7,
"color": "red"
}, {
"value": 6,
"color": "yellow"
}, {
"value": 5,
"color": "green"
}, {
"value": 4,
"color": "red"
}, {
"value": 3,
"color": "yellow"
}, {
"value": 2,
"color": "green"
}, {
"value": 1,
"color": "green"
}]
// Function to automatically generate some squares
function drawSquares() {
let squaresParent = $("#squaresParent");
squaresParent.empty();
let lCALen = cardsArray.length;
for (let i = 0; i < lCALen; ++i) { //make it efficient for checking length
// Creating a text object for display purposes only
let newText = $('<p>').append(cardsArray[i].value);
// Creating a new card
let newCard = $('<div>').attr({
'data-value': cardsArray[i].value,
'style': 'background-color:' + cardsArray[i].color,
'index': i,
'class': 'card'
}).append(newText);
squaresParent.append(newCard);
}
}
drawSquares();
assignEvents();
let firstCard = null;
let secondCard = null;
function compareAndMove(fC, sC) {
//console.log("Switching...");
let firstCardIndex = fC.attr("index");
let secondCardIndex = sC.attr("index");
let beforeSecondCardIndex = 0;
if (secondCardIndex > 0)
beforeSecondCardIndex = secondCardIndex - 1;
let firstCard = cardsArray[firstCardIndex];
let secondCard = cardsArray[secondCardIndex];
let beforeSecond = cardsArray[beforeSecondCardIndex];
if (firstCard.value - 1 === beforeSecond.value) {
let temp = firstCard;
cardsArray[firstCardIndex] = secondCard;
cardsArray[secondCardIndex] = temp;
drawSquares();
assignEvents();
} else {
fC.removeClass("selected");
sC.removeClass("selected");
}
//console.log("Exiting...");
}
function assignEvents() {
$(".card").click(function() {
//console.log("Card clicked");
if (!firstCard) {
firstCard = $(this);
firstCard.addClass("selected");
return;
}
if (!secondCard) {
secondCard = $(this);
secondCard.addClass("selected");
}
compareAndMove(firstCard, secondCard);
firstCard = null;
secondCard = null;
});
}
.card {
width: 50px;
height: 50px;
border-radius: 10px;
border: 1px solid black;
display: inline-block;
text-align: center;
margin: 5px;
}
.selected {
border: 3px solid black;
}
body {
background-color: #ABCDEF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<div id="squaresParent"></div>
</body>
</html>
I think you are looking for something like this..
var currentCard = $(".cards").first();
var currentCardInd = $(currentCard).attr("index");
$(".cards").on("click", function(event){
if(currentCard && parseInt(currentCardInd) < parseInt($(this).attr("index"))){
currentCard.attr("index", $(this).attr("index"));
$(this).attr("index", currentCardInd.toString());
$(this).swapWith(currentCard);
currentCard = $(".cards[index='"+$(this).attr("index")+"']").next();
currentCardInd = $(currentCard).attr("index");
}
});
jQuery.fn.swapWith = function(_with) {
return this.each(function() {
var copyWith = $(_with).clone(true);
var copyOrig = $(this).clone(true);
$(_with).replaceWith(copyOrig);
$(this).replaceWith(copyWith);
});
};
.cards{
padding:10px;
background-color:lightblue;
display:inline-block;
cursor:pointer;
border-radius:5px;
}
#card-7S{
background-color:lightgreen;
}
#card-9D{
background-color:lightyellow;
}
#card-8H{
background-color:lightgray;
}
#card-3D{
background-color:lightpink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div id="card-2d" class="cards" index="2">2D</div>
<div id="card-7S" class="cards" index="4">7S</div>
<div id="card-9D" class="cards" index="7">9D</div>
<div id="card-8H" class="cards" index="10">8H</div>
<div id="card-3D" class="cards" index="15">3D</div>
</div>
You can also check here..
https://jsfiddle.net/nimittshah/7z3y8mb5/
Array.from is the canonical way to get an array of elements
<div class="card" data-value="38">
<img class="front-face" src="PNG/QH.png"/>
</div>
<div class="card" data-value="39">
<img class="front-face" src="PNG/KH.png"/>
</div>
<script>
const [first, second] = Array.from(document.querySelectorAll('.card'))
if (first.dataset.value === second.dataset.value) {
/* do your thing... */
}
</script>
The problem with the code is that querySelectorAll() returns a NodeList which behave as an array but it is not really an array.
The same problem happens with getElementsByClassName() this one return an HTMLCollection which behave as an array but does not include all the prototypes functionalities since it is not really an array.
So you have several options to get the index, after getting the index you can get the element that is before it.
Use call or apply to trick the Array methods
`Array.prototype.indexOf.call(cards, second)`
Iterate manually
`let selectedIndex = 0;
for(let i =0; i < cards.length; i++){
if(cards[i] === second){
selectedIndex = i;
}
};
console.log(selectedIndex)`
Create an array using cards NodeList
const cards = document.querySelectorAll('.card');
const cardsArray = Array.from(cards)
if(firstCard.dataset.value ===
cardsArray[cardsArray.indexOf(secondCard)-1].dataset.value)
Use any library to select the element that returns an array, as jQuery

How to use "toLowerCase();" in java script

I would like to have inputResult toLowerCase I mean that it would not matter if somebody insert the color name with Lower or Big case. I have been trying this but it does not work:
checkResultBtn: function() {
var inputColor = document.getElementById("inputColor");
var inputResult = inputColor.toLocaleLowerCase();
var result = document.getElementById("result");
if (inputResult.value === "") {
result.innerHTML = "no value!!!!";
} else if (inputResult.value === pickedColor) {
result.innerHTML = "BRAVO THAT'S IT!!!";
} else {
result.innerHTML =
"SOMETHING is WRONG!!!";
}
}
The codepen is here: https://codepen.io/hubkubas/pen/eLvbPZ?editors=1010
var inputResult = inputColor.toLowerCase();
toLowerCase expects string. So init inputColor as
var inputColor = document.getElementById("inputColor").value;
then your inputResult will be string and you dont need to call property value
Solution
var colors = [
"red",
"purple",
"blue",
"white",
"green",
"brown",
"orange",
"yellow"
];
var background = document.getElementById("box");
var colorPicker = {
pickColorBtn: function() {
pickedColor = colors[Math.floor(Math.random() * colors.length)];
document.getElementById("pickedColor").innerHTML = pickedColor; //just to see what color has been picked
background.className = pickedColor;
},
checkResultBtn: function() {
var inputColor = document.getElementById("inputColor").value;
var inputResult = inputColor.toLowerCase();
var result = document.getElementById("result");
if (inputResult === "") {
result.innerHTML = "no value!!!!";
} else if (inputResult === pickedColor) {
result.innerHTML = "BRAVO THAT'S IT!!!";
} else {
result.innerHTML =
"SOMETHING is WRONG!!!";
}
}
};
You need to do var inputResult = inputColor.value.toLowerCase() and remove .value from all the conditional statement then it will work fine:
var colors = [
"red",
"purple",
"blue",
"white",
"green",
"brown",
"orange",
"yellow"
];
var background = document.getElementById("box");
var colorPicker = {
pickColorBtn: function() {
pickedColor = colors[Math.floor(Math.random() * colors.length)];
document.getElementById("pickedColor").innerHTML = pickedColor; //just to see what color has been picked
background.className = pickedColor;
},
checkResultBtn: function() {
var inputColor = document.getElementById("inputColor");
var inputResult = inputColor.value.toLowerCase();
var result = document.getElementById("result");
if (inputResult === "") {
result.innerHTML = "no value!!!!";
} else if (inputResult === pickedColor) {
result.innerHTML = "BRAVO THAT'S IT!!!";
} else {
result.innerHTML =
"SOMETHING is WRONG!!!";
}
}
};
#box {
width: 50px;
height: 50px;
border: 3px black solid;
}
.red {
background: red;
}
.purple {
background: purple;
}
.blue {
background: blue;
}
.white {
background: white;
}
.green {
background: green;
}
.brown {
background: brown;
}
.orange {
background: orange;
}
.yellow {
background: yellow;
}
<div id="box"></div>
<div>
<button onclick="colorPicker.pickColorBtn()">Pick a colour</button>
<div id="pickedColor"></div>
<div id="result"></div>
<input id="inputColor" type="text" size="15" placeholder="write the color" />
<button onclick="colorPicker.checkResultBtn()">Check</button>

Change Website Background(image) whit Section

I'm Programming a Website and want that it changes it Backgroundimage when i reached a div Box i found it like i have to do it when i want to change the color of it (the Background) but not how it goes with Images, kinda like this
http://www.formuswithlove.se/
but just with Images
here is the code how to do it with colors if its help for someone
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
body{
margin:0;
padding:0;
background:white;
}
div{
width:100%;
height:1600px;
}
</style>
<script type="text/javascript">
var section = {
sections: [
'section1',
'section2',
'section3'
],
sectionOffset: {},
sectionBackground: {
'section1': 'rgb(0, 0, 0)',
'section2': 'rgb(132, 132, 132)',
'section3': 'rgb(255, 255, 255)'
},
currentSection: null
}
window.onload = function()
{
var looplen = section.sections.length;
for(var i = 0; i < looplen; ++i)
{
section.sectionOffset[section.sections[i]] = document.getElementById(section.sections[i]).offsetTop;
}
setTimeout("initialBackgroundChange()", 50);
}
window.onscroll = function()
{
tryBackgroundChange();
};
function tryBackgroundChange()
{
var looplen = section.sections.length,
match,
backgroundColor;
for(var i = 0; i < looplen; ++i)
{
if(pageYOffset >= section.sectionOffset[section.sections[i]])
{
match = section.sections[i];
}
}
if(match != section.currentSection)
{
section.currentSection = match;
changeBackground();
}
}
function changeBackground()
{
var cbc, // Current background-color
tbc, // Target backgrounc-color
ri, // Red incrementation
gi, // Green incrementation
bi, // Blue incrementation
rgb, // Temporary color from cbc to tbc
smoothness = 20; // Higher is smoother
cbc = getStyle(document.body, 'background-color');
cbc = cbc.substr(4, cbc.length-5);
cbc = cbc.split(", ");
tbc = section.sectionBackground[section.currentSection];
tbc = tbc.substr(4, tbc.length-5);
tbc = tbc.split(", ");
ri = (tbc[0] - cbc[0]) / smoothness;
gi = (tbc[1] - cbc[1]) / smoothness;
bi = (tbc[2] - cbc[2]) / smoothness;
for(var i = 1; i <= smoothness; ++i)
{
rgb = [
Math.ceil(parseInt(cbc[0]) + (ri * i)),
Math.ceil(parseInt(cbc[1]) + (gi * i)),
Math.ceil(parseInt(cbc[2]) + (bi * i))
];
setTimeout("document.body.style.backgroundColor = 'rgb(" + rgb.join(",") + ")'", i * (240/smoothness));
}
}
function initialBackgroundChange()
{
if(pageYOffset == 0)
tryBackgroundChange();
}
function getStyle(elem, name)
{
if (document.defaultView && document.defaultView.getComputedStyle)
{
name = name.replace(/([A-Z])/g, "-$1");
name = name.toLowerCase();
s = document.defaultView.getComputedStyle(elem, "");
return s && s.getPropertyValue(name);
}
else if (elem.currentStyle)
{
if (/backgroundcolor/i.test(name))
{
return (function (el)
{ // get a rgb based color on IE
var oRG=document.body.createTextRange();
oRG.moveToElementText(el);
var iClr=oRG.queryCommandValue("BackColor");
return "rgb("+(iClr & 0xFF)+","+((iClr & 0xFF00)>>8)+","+
((iClr & 0xFF0000)>>16)+")";
})(elem);
}
return elem.currentStyle[name];
}
else if (elem.style[name])
{
return elem.style[name];
}
else
{
return null;
}
}
</script>
</head>
<body>
<div id="section1"></div>
<div id="section2"></div>
<div id="section3"></div>
</body>
</html>
try this:
if($(document).scrollTop() == 400){
$('body').css('background','red')
}

Getting the real background-color of an element?

Currently I want to get the real background-color of a specified object, here, the real means what the people see, for instance, given the following code:
<div id="foo" style="background-color: red">
I am red
<span id="bar">
I have no background, but I am red
</span>
</div>
The real background-color of #bar should be rbg(255,0,0).
Here's what I have so far:
function color_visible(color_str) {
return color_str && !(color_str.substr(0, 4) == "rgba" && color_str.substr(-2, 2) == "0)");
}
function get_bgcolor (obj) {
var ret = $(obj).css("background-color");
if (!color_visible(ret)) ret = $(obj).css("bgcolor");
if (color_visible(ret)) return ret;
if (!$(obj).is("body")) return get_bgcolor($(obj).parent());
return "rgb(255, 255, 255)";
}
But is there a better way to do it?
Demo in Stack Snippet and jsFiddle
function color_visible(color_str) {
return color_str && !(color_str.substr(0, 4) == "rgba" && color_str.substr(-2, 2) == "0)");
}
function get_bgcolor (obj) {
var ret = $(obj).css("background-color");
if (!color_visible(ret)) ret = $(obj).css("bgcolor");
if (color_visible(ret)) return ret;
if (!$(obj).is("body")) return get_bgcolor($(obj).parent());
return "rgb(255, 255, 255)";
}
console.log(get_bgcolor($("#bar")));
console.log(get_bgcolor($("#baz")));
console.log(get_bgcolor($("#foo")));
console.log(get_bgcolor($("body")));
body {
background-color: yellow;
}
.bg_white {
background-color: #FFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div id="foo" style="background-color: red">
I am red
<span id="bar">
I have no background
</span>
<span id="baz" class="bg_white">
I am white
</span>
</div>
I am yellow
</div>
Javascript only version:
function realBackgroundColor(elem) {
var transparent = 'rgba(0, 0, 0, 0)';
var transparentIE11 = 'transparent';
if (!elem) return transparent;
var bg = getComputedStyle(elem).backgroundColor;
if (bg === transparent || bg === transparentIE11) {
return realBackgroundColor(elem.parentElement);
} else {
return bg;
}
}
realBackgroundColor(document.querySelector('#element')); // rgb(255, 255, 255)
http://jsfiddle.net/qnLwsr7y/
Note that it does not take opacity or background images into account.
Try window.getComputedStyle:
window.getComputedStyle(element, null).getPropertyValue("background-color")
This approach is simple and native, but doesn't support IE8
Try this:
var get_bgcolor = function(obj) {
var real = obj.css('background-color');
var none = 'rgba(0, 0, 0, 0)';
if (real === none) {
return obj.parents().filter(function() {
return $(this).css('background-color') != none
}).first().css('background-color');
} else {
return real
}
}
http://jsfiddle.net/bqkwN/
This is a difficult thing to get right :( and I believe a 100% correct result in all cases is impossible.
background-color is not inherited. getComputedStyle only returns what is in elem.style.backgroundColor if there, or otherwise what is derived from the css stylesheets loaded. If these two still don't return a value, it returns rgba(0, 0, 0, 0) in which case you need to climb up the DOM to see what parents elements have. And this is further complicated in the case of frames which may derive their background from the (ie top) frame behind them.
Here is an attempt:
const getCbgcolor = (elem) => {
if (!getCbgcolor.top) getCbgcolor.top= (() => {
try { return window.top.document.documentElement; } catch(e) { return null; /* CORS */}})()
});
while (true) {
let cbg=window.getComputedStyle(elem).getPropertyValue('background-color');
if (cbg && cbg!='rgba(0, 0, 0, 0)' && cbg!='transparent') return cbg;
if (elem===getCbgcolor.top) return 'initial';
elem = elem.parentElement;
if (!elem) return '';
}
}
(An issues with this is that if someone explicitly set an element's background to rgba(0, 0, 0, 0) in the element's style or a css stylesheet you may want that value instead of the calculated value which will not work with this code.)
Try this:
function hexc(colorval) {
var parts = colorval.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
delete(parts[0]);
for (var i = 1; i <= 3; ++i) {
parts[i] = parseInt(parts[i]).toString(16);
if (parts[i].length == 1) parts[i] = '0' + parts[i];
}
color = '#' + parts.join('');
}
var color = '';
$('div#foo').click(function() {
var x = $(this).css('backgroundColor');
hexc(x);
alert(color);
})

Categories