Related
How to change div border-color by input value?
My Code
<div id=divx"> </div>
<button onClick=""> </button>
<script>
function myFunction() {
var color = document.getElemntByID("inpx").value;
document.getElementById("divx").style.borderColor = color;
}
</script>
Don't use on* inline JS handlers/attributes. Use Element.addEventListener(). JS should in in one place only, and that's either your JavaScript tag or file.
getElemntByID should be getElementById
Use input type="color"
Create a reusable setBorderColor(Element, color) function:
const EL = (sel, EL) => (EL||document).querySelector(sel);
const setBorderColor = (el, color) => el.style.borderColor = color;
const EL_inpx = EL("#inpx");
const EL_divx = EL("#divx");
EL_inpx.addEventListener("input", () => {
setBorderColor(EL_divx, EL_inpx.value);
});
setBorderColor(EL_divx, EL_inpx.value);
#divx {border: 10px solid transparent;}
<input id="inpx" type="color" value="#ff0088">
<div id="divx">test</div>
try this: run
function myFunction() {
const color = document.getElementById("inpx").value;
document
.getElementById("divx")
.setAttribute("style", "background-color:" + color);
}
// colors source: https://raw.githubusercontent.com/bahamas10/css-color-names/master/css-color-names.json
const colors = {
"aliceblue": "#f0f8ff",
"antiquewhite": "#faebd7",
"aqua": "#00ffff",
"aquamarine": "#7fffd4",
"azure": "#f0ffff",
"beige": "#f5f5dc",
"bisque": "#ffe4c4",
"black": "#000000",
"blanchedalmond": "#ffebcd",
"blue": "#0000ff",
"blueviolet": "#8a2be2",
"brown": "#a52a2a",
"burlywood": "#deb887",
"cadetblue": "#5f9ea0",
"chartreuse": "#7fff00",
"chocolate": "#d2691e",
"coral": "#ff7f50",
"cornflowerblue": "#6495ed",
"cornsilk": "#fff8dc",
"crimson": "#dc143c",
"cyan": "#00ffff",
"darkblue": "#00008b",
"darkcyan": "#008b8b",
"darkgoldenrod": "#b8860b",
"darkgray": "#a9a9a9",
"darkgreen": "#006400",
"darkgrey": "#a9a9a9",
"darkkhaki": "#bdb76b",
"darkmagenta": "#8b008b",
"darkolivegreen": "#556b2f",
"darkorange": "#ff8c00",
"darkorchid": "#9932cc",
"darkred": "#8b0000",
"darksalmon": "#e9967a",
"darkseagreen": "#8fbc8f",
"darkslateblue": "#483d8b",
"darkslategray": "#2f4f4f",
"darkslategrey": "#2f4f4f",
"darkturquoise": "#00ced1",
"darkviolet": "#9400d3",
"deeppink": "#ff1493",
"deepskyblue": "#00bfff",
"dimgray": "#696969",
"dimgrey": "#696969",
"dodgerblue": "#1e90ff",
"firebrick": "#b22222",
"floralwhite": "#fffaf0",
"forestgreen": "#228b22",
"fuchsia": "#ff00ff",
"gainsboro": "#dcdcdc",
"ghostwhite": "#f8f8ff",
"goldenrod": "#daa520",
"gold": "#ffd700",
"gray": "#808080",
"green": "#008000",
"greenyellow": "#adff2f",
"grey": "#808080",
"honeydew": "#f0fff0",
"hotpink": "#ff69b4",
"indianred": "#cd5c5c",
"indigo": "#4b0082",
"ivory": "#fffff0",
"khaki": "#f0e68c",
"lavenderblush": "#fff0f5",
"lavender": "#e6e6fa",
"lawngreen": "#7cfc00",
"lemonchiffon": "#fffacd",
"lightblue": "#add8e6",
"lightcoral": "#f08080",
"lightcyan": "#e0ffff",
"lightgoldenrodyellow": "#fafad2",
"lightgray": "#d3d3d3",
"lightgreen": "#90ee90",
"lightgrey": "#d3d3d3",
"lightpink": "#ffb6c1",
"lightsalmon": "#ffa07a",
"lightseagreen": "#20b2aa",
"lightskyblue": "#87cefa",
"lightslategray": "#778899",
"lightslategrey": "#778899",
"lightsteelblue": "#b0c4de",
"lightyellow": "#ffffe0",
"lime": "#00ff00",
"limegreen": "#32cd32",
"linen": "#faf0e6",
"magenta": "#ff00ff",
"maroon": "#800000",
"mediumaquamarine": "#66cdaa",
"mediumblue": "#0000cd",
"mediumorchid": "#ba55d3",
"mediumpurple": "#9370db",
"mediumseagreen": "#3cb371",
"mediumslateblue": "#7b68ee",
"mediumspringgreen": "#00fa9a",
"mediumturquoise": "#48d1cc",
"mediumvioletred": "#c71585",
"midnightblue": "#191970",
"mintcream": "#f5fffa",
"mistyrose": "#ffe4e1",
"moccasin": "#ffe4b5",
"navajowhite": "#ffdead",
"navy": "#000080",
"oldlace": "#fdf5e6",
"olive": "#808000",
"olivedrab": "#6b8e23",
"orange": "#ffa500",
"orangered": "#ff4500",
"orchid": "#da70d6",
"palegoldenrod": "#eee8aa",
"palegreen": "#98fb98",
"paleturquoise": "#afeeee",
"palevioletred": "#db7093",
"papayawhip": "#ffefd5",
"peachpuff": "#ffdab9",
"peru": "#cd853f",
"pink": "#ffc0cb",
"plum": "#dda0dd",
"powderblue": "#b0e0e6",
"purple": "#800080",
"rebeccapurple": "#663399",
"red": "#ff0000",
"rosybrown": "#bc8f8f",
"royalblue": "#4169e1",
"saddlebrown": "#8b4513",
"salmon": "#fa8072",
"sandybrown": "#f4a460",
"seagreen": "#2e8b57",
"seashell": "#fff5ee",
"sienna": "#a0522d",
"silver": "#c0c0c0",
"skyblue": "#87ceeb",
"slateblue": "#6a5acd",
"slategray": "#708090",
"slategrey": "#708090",
"snow": "#fffafa",
"springgreen": "#00ff7f",
"steelblue": "#4682b4",
"tan": "#d2b48c",
"teal": "#008080",
"thistle": "#d8bfd8",
"tomato": "#ff6347",
"turquoise": "#40e0d0",
"violet": "#ee82ee",
"wheat": "#f5deb3",
"white": "#ffffff",
"whitesmoke": "#f5f5f5",
"yellow": "#ffff00",
"yellowgreen": "#9acd32"
};
const colorTextInput = document.querySelector("#colorTextInput");
const colorSelector = document.querySelector("#colorSelector");
const updateColorBtn = document.querySelector("#updateColorBtn");
// hexToRgb function source: https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-5624139
const rgbToHex = (r, g, b) => {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
const getHexColor = (color) => {
if (color.length === 0) {
return null;
}
// regex source: https://www.geeksforgeeks.org/how-to-validate-hexadecimal-color-code-using-regular-expression/
const isHexColor = new RegExp("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$").test(color);
if (isHexColor) {
// Three digit hex to six digit converter
// Source: https://gomakethings.com/converting-a-color-from-a-three-digit-hexcolor-to-a-six-digit-hexcolor-with-vanilla-js/
if (color.length === 4) {
hexColor = color.substr("#".length).split('').map(function (hex) {
return hex + hex;
}).join('');
return "#" + hexColor;
}
return color;
}
else {
if (color.startsWith("rgba(")) {
color = "rgb" + color.substr("rgba".length);
}
if (color.startsWith("rgb(")) {
const csv = color.substr("rgb(".length, color.length - ("rgb(".length + ")".length));
const rgb = csv.split(",").map(function(item) {
return Number(item);
});
if (rgb.length === 3 || rgb.length === 4) {
return rgbToHex(rgb[0], rgb[1], rgb[2]);
}
else {
return null;
}
}
else {
let hexColor = colors[color.toLowerCase()];
if (typeof hexColor === "string") {
return hexColor;
}
return null;
}
}
}
colorTextInput.addEventListener("input", () => {
let hexColor = getHexColor(colorTextInput.value);
if (hexColor !== null) {
colorTextInput.classList.remove("invalid");
colorSelector.value = hexColor;
}
else {
colorTextInput.classList.add("invalid");
}
});
colorSelector.addEventListener("input", () => {
colorTextInput.classList.remove("invalid");
colorTextInput.value = colorSelector.value;
})
updateColorBtn.addEventListener("click", () => {
document.getElementById("colorOutput").style.borderColor = colorSelector.value;
});
#colorOutput
{
width: 50px;
height: 50px;
border-width: 3px;
border-style: solid;
margin-bottom: 1rem;
}
#colorTextInput {
outline: none;
}
#colorTextInput.invalid {
border-color: #d93025;
}
#colorControls {
display: flex;
gap: .25rem;
}
#colorControls > * {
border-radius: 0.25rem;
border: 1px solid black;
}
#colorSelector {
width: 2rem;
outline: none;
-webkit-appearance: none;
}
#colorSelector::-webkit-color-swatch-wrapper {
padding: 0;
}
#colorSelector::-webkit-color-swatch {
border: none;
margin: 1px 0px;
border-radius: .25rem;
}
<div id="colorOutput" style="border-color: #4169e1;"></div>
<div id="colorControls">
<input id="colorTextInput" type="text" value="royalblue">
<input id="colorSelector" type="color" value="#4169e1">
<button id="updateColorBtn">Set border color</button>
</div>
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>
I am creating a simple picture matching game and I will love to make sure when the picture is clicked once, the event listener is removed, this will help me stop the user from clicking on the same image twice to get a win, and then when the user clicks on another element the listener should be added back, I tried doing this with an if statement but the listener is only removed and never added back, I decided to reload the page which somehow makes it look like a solution but I need a better solution that can help me not to reload the page but add the listener back so that the element can be clicked again after the last else if statement run.
here is the sample code below.
//Selecting query elements
const aniSpace = document.querySelector(".container");
const firstCard = document.querySelector("#fstcard");
const secondCard = document.querySelector("#sndcard");
const thirdCard = document.querySelector("#thrdcard");
const playGame = document.querySelector('#play');
const scores = document.querySelector('.scoreboard');
count = 0;
var firstIsClicked = false;
var isCat = false;
var isElephant = false;
var isDog = false;
var isButterfly = false;
var isEmpty = false;
const animatchApp = () => {
const animals = {
cat: {
image: "asset/images/cat.png",
name: "Cat"
},
dog: {
image: "asset/images/puppy.png",
name: "Dog"
},
elephant: {
image: "asset/images/elephant.png",
name: "Elephant"
},
butterfly: {
image: "asset/images/butterfly.png",
name: "butterfly"
}
}
var score = 0;
firstCard.addEventListener('click', function firstBtn() {
var type = animals.cat.name;
if (firstIsClicked === true && isCat === true) {
firstCard.innerHTML = `<img src="${animals.cat.image}">`;
firstCard.classList.add('display');
alert("You won");
score = score + 50;
console.log(score);
document.getElementById('scores').innerHTML = score;
firstIsClicked = false;
isElephant = false;
if (score >= 200){
alert("You are unstoppable, Game won.");
count = 0;
score = 0;
document.getElementById('scores').innerHTML = score;
document.getElementById('attempts').innerHTML = count;
}
firstCard.removeEventListener('click', firstBtn);
} else if (firstIsClicked === false) {
firstCard.innerHTML = `<img src="${animals.cat.image}">`;
firstCard.classList.add('display');
firstIsClicked = true;
isCat = true;
firstCard.removeEventListener('click', firstBtn);
} else if (firstIsClicked === true && isCat != true) {
alert("Not Matched");
count++;
document.getElementById('attempts').innerHTML = count;
firstCard.innerHTML = '';
secondCard.innerHTML = '';
thirdCard.innerHTML = '';
firstCard.classList.remove('display');
secondCard.classList.remove('display');
thirdCard.classList.remove('display');
firstIsClicked = false;
isCat = false;
isDog = false;
isElephant = false;
isButterfly = false;
score = 0;
document.getElementById('scores').innerHTML = score;
location.reload(true);
}
})
secondCard.addEventListener('click', function secondBtn() {
var type = animals.elephant.name;
if (firstIsClicked === true && isElephant === true) {
secondCard.innerHTML = `<img src="${animals.elephant.image}">`;
secondCard.classList.add('display');
alert("You won");
score = score + 50;
console.log(score);
document.getElementById('scores').innerHTML = score;
firstIsClicked = false;
isElephant = false;
if (score >= 200){
alert("You are unstoppable, Game won.");
count = 0;
score = 0;
document.getElementById('scores').innerHTML = score;
document.getElementById('attempts').innerHTML = count;
}
secondCard.removeEventListener('click', secondBtn);
} else if (firstIsClicked === false) {
secondCard.innerHTML = `<img src="${animals.elephant.image}">`;
secondCard.classList.add('display');
firstIsClicked = true;
isElephant = true;
secondCard.removeEventListener('click', secondBtn);
} else if (firstIsClicked === true && isElephant != true) {
alert("Not Matched");
count++;
document.getElementById('attempts').innerHTML = count;
firstCard.innerHTML = '';
secondCard.innerHTML = '';
thirdCard.innerHTML = '';
firstCard.classList.remove('display');
secondCard.classList.remove('display');
thirdCard.classList.remove('display');
firstIsClicked = false;
isCat = false;
isDog = false;
isElephant = false;
isButterfly = false;
score = 0;
document.getElementById('scores').innerHTML = score;
location.reload(true);
}
})
thirdCard.addEventListener('click', function thirdBtn() {
var type = animals.dog.name;
if (firstIsClicked === true && isDog === true) {
thirdCard.innerHTML = `<img src="${animals.dog.image}">`;
thirdCard.classList.add('display');
alert("You won");
score = score + 50;
console.log(score);
document.getElementById('scores').innerHTML = score;
firstIsClicked = false;
isDog = false;
if (score >= 200){
alert("You are unstoppable, Game won.");
count = 0;
score = 0;
document.getElementById('scores').innerHTML = score;
document.getElementById('attempts').innerHTML = count;
}
thirdCard.removeEventListener('click', thirdBtn);
} else if (firstIsClicked === false) {
thirdCard.innerHTML = `<img src="${animals.dog.image}">`;
thirdCard.classList.add('display');
firstIsClicked = true;
isDog = true;
thirdCard.removeEventListener('click', thirdBtn);
} else if (firstIsClicked === true && isDog != true) {
alert("Not Matched");
count++;
document.getElementById('attempts').innerHTML = count;
firstCard.innerHTML = '';
secondCard.innerHTML = '';
thirdCard.innerHTML = '';
firstCard.classList.remove('display');
secondCard.classList.remove('display');
thirdCard.classList.remove('display');
firstIsClicked = false;
isCat = false;
isDog = false;
isElephant = false;
isButterfly = false;
score = 0;
document.getElementById('scores').innerHTML = score;
location.reload(true);
}
})
document.getElementById('attempts').innerHTML = count;
}
animatchApp();
.h1 {
text-align: center;
background-color: azure;
background-image: url("");
}
* {
box-sizing: border-box;
}
.container {
width: 500px;
}
.card1 {
background-color: blue;
float: left;
width: 30%;
padding: 10px;
height: 150px; /* Should be removed. Only for demonstration */
border: 1px solid rgb(179, 177, 177);
transition: transform 0.8s;
transform-style: preserve-3d;
}
.card2 {
background-color: blue;
float: left;
width: 30%;
padding: 10px;
height: 150px; /* Should be removed. Only for demonstration */
border: 1px solid rgb(179, 177, 177);
transition: transform 0.8s;
transform-style: preserve-3d;}
.card3 {
background-color: blue;
float: left;
width: 30%;
padding: 10px;
height: 150px; /* Should be removed. Only for demonstration */
border: 1px solid rgb(179, 177, 177);
transition: transform 0.8s;
transform-style: preserve-3d;
}
.scoreboard {
float: left;
width: 100%;
padding: 10px;
height: 150px; /* Should be removed. Only for demonstration */
}
img {
width: 100%;
height: 100%;
background-color: white;
}
.display {
background-color: white;
transform: rotateY(180deg);
}
<div class="container">
<h1 class="h1">Animatch</h1>
<div class="first">
<div class="card1" id="fstcard"></div>
<div class="card1" id="sndcard"></div>
<div class="card1" id="thrdcard"></div>
</div>
</div>
<div class="scoreboard">
<p>
<button id="play" onclick="animatchApp()">Play</button>
<br>
Score: <span id="scores">0</span>
<br>
Failed attempts: <span id="attempts"></span>
</p>
</div>
you have to define function outside of onclick because you will need this function reference to remove or add it to eventlistener later
see a example below
function onload(){
var main = document.querySelector(".main"),
btns = main.querySelectorAll(".buttons input"),
box = main.querySelector(".box")
btns[0].addEventListener("click",function(){
box.addEventListener("click",functionForEvent)
})
btns[1].addEventListener("click",function(){
box.removeEventListener("click",functionForEvent)
})
function functionForEvent(e){
console.log("clicked")
}
}
onload()
<div class="main">
<div class="box" style="height:120px;width:120px;border:1px solid black;">Click Me</div>
<div class="buttons">
<input type="button" value="Add Event">
<input type="button" value="Remove Event">
</div>
</div>
Here is an example, that shows how to remove the click event from the item clicked and add it to the other items.
It colors the items that can be clicked green, and the item that can't be clicked red.
To keep the example short, it doesn't check, if the elements it operates on, are well defined.
function myonload() {
let elems = document.querySelectorAll('.mydiv');
for(let i = 0; i < elems.length; ++i) {
let elem = elems[i];
elem.addEventListener('click', mydiv_clicked);
}
}
function mydiv_clicked(e) {
let elems = document.querySelectorAll('.mydiv');
for(let i = 0; i < elems.length; ++i) {
let elem = elems[i];
if(elem == e.target) {
elem.removeEventListener('click', mydiv_clicked);
elem.classList.add('mycolor_clicked');
elem.classList.remove('mycolor');
// Do additional logic here
} else {
elem.addEventListener('click', mydiv_clicked);
elem.classList.remove('mycolor_clicked');
elem.classList.add('mycolor');
// Do additional logic here
}
}
}
.mydiv {
height:30px;
width: 200px;
border:1px solid black;
margin-bottom:2px;
}
.mycolor {
background-color:#00ff00;
}
.mycolor_clicked {
background-color:#ff0000;
}
<body onload="myonload()">
<div class="mydiv mycolor">First area</div>
<div class="mydiv mycolor">Second area</div>
<div class="mydiv mycolor">Third area</div>
</body>
The example shown here does not need to check if an event handler already exists, as adding the same event handler twice, replaces the existing one.
You could also add a custom attribute to your elements and toggle it, instead of adding and removing event listeners as shown here and name your attribute data-something, for example data-can-be-clicked.
I am using Chart.js to construct pie chart, is there any way to concatenate the Count to the label (Displaying numbers and percentages in a pie chart legend)?
createChart : function() {
debugger;
var chartData = [60, 90, 120, 150];
var chartLabels = ['apples','bananas','oranges','pears'];
var chartCanvas = component.find("chart").getElement();
var chart = new Chart(chartCanvas, {
type: 'pie',
data: {
labels: chartLabels,
datasets: [
{
label: "test",
data: chartData,
borderWidth: 0,
backgroundColor: [
"#f43004",
"#decf3f",
"#FFA500"
]
}
]
},
options: {
cutoutPercentage: 1,
maintainAspectRatio: false,
legend: {
display: true,
position:'right',
fullWidth:false,
reverse:true,
labels: {
fontColor: '#000',
fontSize:10,
fontFamily:"Arial, sans-serif SANS_SERIF"
},
layout: {
padding: 70,
}
}
}
});
}
I am trying to construct chart like this:
Please provide any suggestions or pointers to achieve this.
Thank you in advance.
You can use html-legends feature so you can customize the Chart.js legend:
legendCallback : function (chart) {
var text = [];
text.push('<ul class="0-legend">');
var ds = chart.data.datasets[0];
var sum = ds.data.reduce(function add(a, b) {
return a + b;
}, 0);
for (var i = 0; i < ds.data.length; i++) {
text.push('<li>');
var perc = Math.round(100 * ds.data[i] / sum, 0);
text.push('<span style="background-color:' + ds.backgroundColor[i] + '">' + '</span>' + chart.data.labels[i] + ' (' + ds.data[i] + ') (' + perc + '%)');
text.push('</li>');
}
text.push('</ul>');
return text.join("");
}
Here is a fiddle: https://jsfiddle.net/beaver71/b5hdn9gw/
var ctx = document.getElementById("myChart").getContext('2d');
var chartData = [60, 90, 120, 150];
var chartLabels = ['apples','bananas','oranges','pears'];
var chart = new Chart(ctx, {
type: 'pie',
data: {
labels: chartLabels,
datasets: [{
backgroundColor: [
"#f43004",
"#decf3f",
"#FFA500",
"#9b59b6",
],
data: chartData
}]
},
options: {
legend: {
display: false
},
legendCallback: function(chart) {
var text = [];
text.push('<ul class="0-legend">');
var ds = chart.data.datasets[0];
var sum = ds.data.reduce(function add(a, b) { return a + b; }, 0);
for (var i=0; i<ds.data.length; i++) {
text.push('<li>');
var perc = Math.round(100*ds.data[i]/sum,0);
text.push('<span style="background-color:' + ds.backgroundColor[i] + '">' + '</span>' + chart.data.labels[i] + ' ('+ds.data[i]+') ('+perc+'%)');
text.push('</li>');
}
text.push('</ul>');
return text.join("");
}
}
});
var myLegendContainer = document.getElementById("legend");
// generate HTML legend
myLegendContainer.innerHTML = chart.generateLegend();
// bind onClick event to all LI-tags of the legend
var legendItems = myLegendContainer.getElementsByTagName('li');
for (var i = 0; i < legendItems.length; i += 1) {
legendItems[i].addEventListener("click", legendClickCallback, false);
}
function legendClickCallback(event) {
event = event || window.event;
var target = event.target || event.srcElement;
while (target.nodeName !== 'LI') {
target = target.parentElement;
}
var parent = target.parentElement;
var chartId = parseInt(parent.classList[0].split("-")[0], 10);
var chart = Chart.instances[chartId];
var index = Array.prototype.slice.call(parent.children).indexOf(target);
var meta = chart.getDatasetMeta(0);
console.log(index);
var item = meta.data[index];
if (item.hidden === null || item.hidden === false) {
item.hidden = true;
target.classList.add('hidden');
} else {
target.classList.remove('hidden');
item.hidden = null;
}
chart.update();
}
body {
font-family: 'Arial';
}
.container {
margin: 15px auto;
}
#chart {
float: left;
width: 70%;
}
#legend {
float: right;
}
[class$="-legend"] {
list-style: none;
cursor: pointer;
padding-left: 0;
}
[class$="-legend"] li {
display: block;
padding: 0 5px;
}
[class$="-legend"] li.hidden {
text-decoration: line-through;
}
[class$="-legend"] li span {
border-radius: 5px;
display: inline-block;
height: 10px;
margin-right: 10px;
width: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.js"></script>
<div class="container">
<h2>Chart.js — Pie Chart Demo Percent</h2>
<div>
<div id="chart"><canvas id="myChart"></canvas></div>
<div id="legend"></div>
</div>
</div>
var ctx = document.getElementById("myChart").getContext('2d');
var chartData = [60, 90, 120, 150];
var chartLabels = ['apples','bananas','oranges','pears'];
var chart = new Chart(ctx, {
type: 'pie',
data: {
labels: chartLabels,
datasets: [{
backgroundColor: [
"#f43004",
"#decf3f",
"#FFA500",
"#9b59b6",
],
data: chartData
}]
},
options: {
legend: {
display: false
},
legendCallback: function(chart) {
var text = [];
text.push('<ul class="0-legend">');
var ds = chart.data.datasets[0];
var sum = ds.data.reduce(function add(a, b) { return a + b; }, 0);
for (var i=0; i<ds.data.length; i++) {
text.push('<li>');
var perc = Math.round(100*ds.data[i]/sum,0);
text.push('<span style="background-color:' + ds.backgroundColor[i] + '">' + '</span>' + chart.data.labels[i] + ' ('+ds.data[i]+') ('+perc+'%)');
text.push('</li>');
}
text.push('</ul>');
return text.join("");
}
}
});
var myLegendContainer = document.getElementById("legend");
// generate HTML legend
myLegendContainer.innerHTML = chart.generateLegend();
// bind onClick event to all LI-tags of the legend
var legendItems = myLegendContainer.getElementsByTagName('li');
for (var i = 0; i < legendItems.length; i += 1) {
legendItems[i].addEventListener("click", legendClickCallback, false);
}
function legendClickCallback(event) {
event = event || window.event;
var target = event.target || event.srcElement;
while (target.nodeName !== 'LI') {
target = target.parentElement;
}
var parent = target.parentElement;
var chartId = parseInt(parent.classList[0].split("-")[0], 10);
var chart = Chart.instances[chartId];
var index = Array.prototype.slice.call(parent.children).indexOf(target);
var meta = chart.getDatasetMeta(0);
console.log(index);
var item = meta.data[index];
if (item.hidden === null || item.hidden === false) {
item.hidden = true;
target.classList.add('hidden');
} else {
target.classList.remove('hidden');
item.hidden = null;
}
chart.update();
}
body {
font-family: 'Arial';
}
.container {
margin: 15px auto;
}
#chart {
float: left;
width: 70%;
}
#legend {
float: right;
}
[class$="-legend"] {
list-style: none;
cursor: pointer;
padding-left: 0;
}
[class$="-legend"] li {
display: block;
padding: 0 5px;
}
[class$="-legend"] li.hidden {
text-decoration: line-through;
}
[class$="-legend"] li span {
border-radius: 5px;
display: inline-block;
height: 10px;
margin-right: 10px;
width: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.js"></script>
<div class="container">
<h2>Chart.js — Pie Chart Demo Percent</h2>
<div>
<div id="chart"><canvas id="myChart"></canvas></div>
<div id="legend"></div>
</div>
</div>
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>