Javascript: Compare backgroundColor set by javascript - javascript

How can compare the background color of an element, when the color is set with javascript, I want a function that toggles the backgroundColor:
function toggleBgColor() {
if(document.getElementById("id").style.backgroundColor === "blue"){
document.getElementById("ide").style.backgroundColor = "red");
}else{
document.getElementById("ide").style.backgroundColor = "blue");
}
}
The problem is that the comparison is always false, so my background is always blue, but it want the color to switch from blue to red and vice versa when the function is called

Use Window.getComputedStyle() — https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle.

The backgroundColor property can get tricky with various representations of color. Consider changing classes instead:
JavaScript
function toggleBgColor() {
var el = document.getElementById("id");
var hasBlue = el.classList.contains('blue');
el.classList.toggle('blue', !hasBlue);
el.classList.toggle('red', hasBlue);
}
CSS
.blue {
background-color: blue;
}
.red {
background-color:red;
}
Or more semantically correct:
JavaScript
function toggleBgColor() {
document.getElementById("id").classList.toggle('selected');
}
CSS
#id {
background-color:red;
}
#id.selected {
background-color:blue;
}

Why not simply add a class that gets toggled?
function toggleBgClass() {
var element = document.getElementById('id');
if (element.classList.contains('blue')) {
element.classList.add('blue');
element.classList.remove('red');
}
else {
element.classList.add('red');
element.classList.remove('blue');
}
}
Now, in your CSS:
.blue {
background-color: blue;
}
.red {
background-color: red;
}

You have written the incorrect code.
The correct code is
function toggleBgColor()
{
if(document.getElementById("ptag").style.backgroundColor === "blue")
{
document.getElementById("ptag").style.backgroundColor = "red";
}
else
{
document.getElementById("ptag").style.backgroundColor = "blue";
}
};
Html File
<html>
<head>
<script type="text/javascript" src="js/backgroundtry.js"></script>
</head>
<body>
<p id="ptag" style="background-color:blue;">
Hi How are you
</p>
<a class="mybutton" onclick="toggleBgColor();">
Change Color
</a>
</body>
</html>

Related

How do you get/set non root CSS variables from JavaScript

Lots of answers on how to get/set "root" CSS variables but none that I've found on how to get/set NON root CSS variables.
NOTE: This is NOT answer: https://stackoverflow.com/a/36088890/104380 That answer only handles root variables and or variables on elements, not on classes
Also: These are not answers (from: https://www.google.com/search?q=get%2Fset+css+variables). Checked the first page of links. All of them only handle root variables. I'm trying to deal with non-root variables.
.foo {
--fg-color: red;
}
.bar {
--fg-color: blue;
}
div {
color: var(--fg-color);
}
<div class="foo">foo</div>
<div class="bar">foo</div>
How do you get someFunctionToGetCSSVariable('.foo', '--fg-color') (yes, I made that up). The point is I want to get/set the --fg-color variable on the .foo CSS rule. Whatever the solution is, getting the value it should return 'red' or '#FF0000') and how do you set it to something else?
I think what OP tries to do is not to change the all elements of that certain class, but to change the class itself, there is a difference. What you need (if I understood well) is actually cssRules change on the certain class. I've created a quick (and dirty) snippet of how to search the cssRules and change the CSS properties in it (including custom one):
<html>
<head>
<style>
.foo {
--fg-color: red;
}
</style>
</head>
<body>
<div class="foo">lorem ipsum</div>
<script>
window.onload = function() {
rules = document.styleSheets[0].cssRules
for (var r in rules) {
if (rules[r].selectorText == ".foo") {
rules[r].style.setProperty('--fg-color', 'blue');
alert('hi');
break;
}
}
};
</script>
</body>
</html>
You could make use of the fact that we have cascading style sheets.
It depends on exactly what your structure is of course, (e.g. are there style elements buried in body?).
For the simple case you could add another stylesheet onto the bottom of the head element.
<!doctype html>
<html>
<head>
<style>
.foo {
--fg-color: red;
}
.bar {
--fg-color: blue;
}
div {
color: var(--fg-color);
}
</style>
</head>
<body>
<div class="foo">foo</div>
<div class="bar">foo</div>
<button>Click me</button>
<script>
const button = document.querySelector('button');
button.addEventListener('click', function () {
const head = document.querySelector('head');
const style = document.createElement('style');
style.innerHTML = '.foo { --fg-color: lime; }';
head.appendChild(style);
button.style.display = 'none';
});
</script>
</body>
</html>
Of course, it could get messy if this happens more than once. You'd want to remember that you'd added a style sheet and get rid of it before adding another one, or alter it in situ, depending on exactly what the situation is. And if there is styling scattered in the body you'll have to add the stylesheet to the bottom of that.
Looks like I have to iterate through all the stylesheets and find the rule. Here's one try.
function getCSSRuleBySelector(selector) {
for (let s = 0; s < document.styleSheets.length; ++s) {
const rules = document.styleSheets[s].cssRules;
for (let i = 0; i < rules.length; ++i) {
const r = rules[i];
if (r.selectorText === selector) {
return r;
}
}
}
}
function setCSSVariableBySelector(selector, varName, value) {
const rule = getCSSRuleBySelector(selector);
rule.style.setProperty(varName, value);
}
function getCSSVariableBySelector(selector, varName) {
const rule = getCSSRuleBySelector(selector);
return rule.style.getPropertyValue(varName);
}
console.log('was:', getCSSVariableBySelector('.foo', '--fg-color'));
setCSSVariableBySelector('.foo', '--fg-color', 'green');
.foo {
--fg-color: red;
}
.bar {
--fg-color: blue;
}
div {
color: var(--fg-color);
}
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="bar">bar</div>
<div class="bar">bar</div>
You can use document's styleSheets property to access the CSS rules of the linked .css file, and perform some operations on it to get the value of the custom css variable.
To set a value of custom CSS variable (of the class itself), you can create a new style element, and add a rule for it.
function getStyle(selector, prop) {
let rules = getRule(selector).cssText;
return rules.split(prop + ":")[1].replace(";", "").replace("}", "").trim();
}
function setStyle(selector, prop, val) {
let style = document.querySelector("style.customStyle");
if(style === null){
style = document.createElement("style");
style.className = "customStyle";
style.innerHTML = `${selector}{${prop}:${val}}`;
document.head.appendChild(style);
} else{
style.innerHTML += `${selector}{${prop}:${val}}`;
}
}
function getRule(selector) {
let rulesObj = document.styleSheets[0];
let classes = rulesObj.rules || rulesObj.cssRules;
classes = Object.values(classes)
let rules = classes.filter(c => c.selectorText === selector)[0];
return rules;
}
console.log(getStyle(".foo", "--fg-color"));
console.log(getStyle(".bar", "--fg-color"));
document.querySelector("button").onclick = ()=>{
setStyle(".bar", "--fg-color", "green");
}
.foo {
--fg-color: red;
}
.bar {
--fg-color: blue;
}
div {
color: var(--fg-color);
}
<div class="foo">foo</div>
<div class="bar">foo</div>
<div><button>Click</button></div>
Get
Iterate all styles
Styles can be injected via external CSS file, a <style> tag (on the page) or style attribute (irrelevant to you).
const results = [];
const SELECTOR = '.foo';
const PROP = '--bar';
[...document.styleSheets].forEach(sheet => {
[...sheet?.cssRules].forEach(rule => {
// you should probably use regex to find PROP (so it won't match `--bar-x` for example)
if( rule.cssText.includes(SELECTOR) && rule.cssText.includes(PROP) ){
results.push(rule.cssText)
}
})
});
console.log(results)
.foo { --bar: red }
Now you need to parse the result and extract the property value.
You did not specify in your question if CSS selectors' specificity should be regarded, which makes things a lot more complex.
There might also be selectors which implicitly applies style properties to elements. Examples of different specificities:
/* assuming '.foo' is a div child of <body> */
.foo { --x:1 }
body .foo { --x:2 }
body > div { --x:3 }
body * { --x:4 }
div { --x:5 }
Set
Regarding setting, you need to dynamically add a rule or a style tag:
document.head.insertAdjacentHTML("beforeend", `<style id="whatever">--fg-color: red;</style>`)
And when you want to update it, just overwrite the #whatever <style> with innerHTML.
To set the value you can use document.querySelectorAll and the setProperty method on the style of each object:
function setCssVariable(selector, variable, value) {
document.querySelectorAll(selector).forEach(function (element) {
element.style.setProperty(variable, value);
});
}
setCssVariable(".foo", "--fg-color", "black");
And to get the value, assuming all elements of the class have the same value, you can use a similar approach using document.querySelector and the getProperty method on style of the element:
function getCssVariable(selector, variable) {
const element = document.querySelector(selector);
if (element !== null) {
return element.style.getPropertyValue(variable);
}
}
getCssVariable(".foo", "--fg-color");
You can read the variable value from the getComputedStyle method of JS and set the
variable value with style attribute.
let foo = document.querySelector('.foo');
/*You can get the value of variable property from the element where you used the variable*/
//console.log(getComputedStyle(foo).getPropertyValue('--fg-color'));
/*You can set the variable value like this for every element where used the variable and want to choose at runtime with js */
//foo.style.cssText = '--fg-color:black;';
function setCSSProperty(cls, prop, val){
let els = document.querySelectorAll(cls);
if(els){
els.forEach(el => {
el.style.cssText += `${prop}:${val};`
})
}
}
function getCSSPropertyData(cls, prop){
let els = document.querySelectorAll(cls);
let data = [];
if(els){
els.forEach((el,ind) => {
let cs = getComputedStyle(el);
data[ind] = cs.getPropertyValue(prop).trim();
});
}
return data;
}
console.log(getCSSPropertyData('.foo', '--fg-color'));
setCSSProperty('.foo', '--fg-color', 'green');
.foo {
--fg-color: red;
}
.bar {
--fg-color: blue;
}
div {
color: var(--fg-color);
}
<div class="foo">foo</div>
<div class="bar">foo</div>

creat button for change background color

I want to create two buttons in HTML called 'green' and 'red'. When clicking on them, the style "background-color: {COLOR-SELECTED}" should be changed dynamically.
var verde = document.getElementById('verde')
var vermelho = document.getElementById('vermelho')
var body = document.querySelector('body')
function verde() {
body.className = "verde";
}
function vermelho() {
body.className = "vermelho";
}
.verde {
background-color: darkgreen;
}
.vermelho {
background-color: darkred;
}
<body>
<button class="verde" onclick="verde ()" id="verde"></button>
<button class="vermelho" onclick="vermelho ()" id="vermelho"></button>
</body>
You should use the classList API to add or remove a class to body.
More info HERE
function verde () {
body.classList.remove('vermelho');
body.classList.add('verde');
}
Here are a few changes I've made:
Remove the space between the function name and the () in the HTML.
Removed the first two lines of the javascript – you never use these variables.
Changed querySelector to getElementsByTagName, which creates a list of elements, so that you can select the first one using [0]
The snippet below should work as expected:
var body = document.getElementsByTagName('body')[0];
function verde() {
body.className = "verde";
}
function vermelho() {
body.className = "vermelho";
}
.verde {
background-color: darkgreen;
}
.vermelho {
background-color: darkred;
}
<body class="none">
<button class="verde" onclick="verde()" id="verde"></button>
<button class="vermelho" onclick="vermelho()" id="vermelho"></button>
</body>

Toggle between pool of classes in Javascript

How to use vanilla JavaScript or jQuery to toggle between two classes is a question, that has been asked and answered many times on stackoverflow and other websites.
What I haven't found though is a solution to use the onclick event to toggle between a pool of classes.
What I want to achive is this:
I have a body element with the class "yellow".
When clicking a button, I want this class removed from the body and replaced with the class "green". Clicking the button again should change the class to "red" and next time to "blue" and finally back to "yellow" and so on.
Any ideas are much appreciated.
Here's a simple answer, you can modify it so you push or pop more classes into the array and so on.
var classes = ["yellow", "green", "red"];
var button = $("#changeColor");
var count = 1;
button.on("click", function(){
$("#foo").removeClass();
$("#foo").addClass(classes[count]);
count++;
if(count > 2){
count = 0;
}
});
.yellow {
background-color: yellow;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo" style="width: 200px; height: 50px;" class="yellow">
FOO
</div>
<button id="changeColor">CHANGE</button>
Have a look at below snippet. Please note, in pool all colors should be unique otherwise you have to create an extra variable to track the index of applied color.
var pool = ['yellow', 'green', 'red', 'blue']
var body = document.getElementsByTagName('body')[0];
body.style.backgroundColor = 'yellow';
function changeColor() {
var bodyColor = body.style.backgroundColor;
var appliedIndex = pool.indexOf(bodyColor);
if (appliedIndex === pool.length - 1) {
body.style.backgroundColor = pool[0];
} else {
body.style.backgroundColor = pool[appliedIndex + 1];
}
}
<button id="change" onClick="changeColor()">Change</button>

JavaScript in HTML changing background

I have no idea what I am doing. I thought I had everything going well with html, then I had to add some simple javascript.
I am just trying to change the background color when the user clicks a button.
This is what I have so far:
CSS
body {
background-color:grey;
}
Javascript
function changeBackground() {
if (document.body.style.backgroundColor = 'grey')
{
document.body.style.backgroundColor = 'black';
}
else
{
document.body.style.backgroundColor = 'grey';
}
}
Html
<button type="button" onclick="changeBackground()">
Click Me!
</button>
Your if clause is wrong (you are assigning instead of testing the background color):
function changeBackground() {
if (document.body.style.backgroundColor == 'grey'){
document.body.style.backgroundColor = 'black';
} else {
document.body.style.backgroundColor = 'grey';
}
}
Richard, I'll offer an alternative to all of the other answers - and you should consider the following structure in all web front-end that you develop.
HTML is what you display, JS is how it behaves, CSS is how it is styled.
That said, try to avoid styling elements with JS but rather toggle a class and allow CSS to do the work. In your case, you could write:
function changeBackground()
{
$(body).toggleClass('dark');
}
<button type="button" onclick="changeBackground()">
Click Me!
</button>
body
{
background-color: grey;
}
body.dark
{
background-color: black;
}
Here, we're simply toggling a class on and off the body element, the CSS will 'respond' accordingly. We have a nice clear separation of concerns.
You may choose your class name to make more sense than dark, but the idea is your JS doesn't care about colors and details of styling.
Try:
$("button").click(function(){
$("body").css("background-color", "blue");
});
Try the FIDDLE,
The problem is you are using assignment operator = instead of comparison operator == or ===
function changeBackground() {
if (document.body.style.backgroundColor == 'grey') {
document.body.style.backgroundColor = 'red';
} else {
document.body.style.backgroundColor = 'grey';
}
}
Hope this works for you

javascript .style property of span tag in anchor tag not working as expected

I am trying to style some buttons for my website
This is my html
<div>
<a class="page_numbers"><span>100</span></a>
<a class="page_numbers"><span>2</a></span></div>
this is my css
.page_numbers{
display:table-cell;
border:solid;
padding:0px;
border-radius:100px;
width:50px;
height:50px;
text-align:center;
vertical-align:middle;
}
div {
display:table;
border-spacing:10px;
}
}
and finally this is my javascript
var obj=document.getElementsByClassName("page_numbers")
for (i in obj){
console.log(obj[i].children)
obj[i].children[0].style.color="black"
obj[i].style.borderColor="rgb(85,170,255)"
function jun(i){
obj[i].addEventListener('mouseenter',function(){obj[i].style.background="yellow";obj[i].style.color="red"},true)
//
obj[i].addEventListener('mouseleave',function(){
obj[i].style.background="white";
obj[i].style.color="rgb(12,31,22)";},true)
}
jun(i);
}
the background color changes on mouseleave and enter but not the font color...I suppose I am doing something wrong along the way or I am missing a fundamental concept
this is my jsfiddle link
http://jsfiddle.net/repzeroworld/boqv8hak/
advice please..still learning JS
Firstly, all of this should be in CSS and is trivial to do so
.page_numbers:hover
{
background-color: yellow;
}
.page_numbers:hover span
{
color: red;
}
Now the issue you are having is that on about the 4th line of your JS you explicitly set the color of the child element (the span) inside the .page_number element to be black. Now on you mouse enter you are setting the color on the page_number element, but since the child has a style applied directly to it (i.e. color: black) it does not inherit the parent style. Inline styles (i.e. style applied directly to the element with the style="" attribute, which is what JS does) always have the highest precedence. This is why it is generally not best practice to put inline styles on an element, as you have just seen, they are pretty much impossible to override. So change either the child to not have an explicit style, or on the mouse enter change the child not the parent
var obj = document.getElementsByClassName("page_numbers")
for (i in obj) {
console.log(obj[i].children)
obj[i].children[0].style.color = "black"
obj[i].style.borderColor = "rgb(85,170,255)"
function jun(i) {
obj[i].addEventListener('mouseenter', function () {
obj[i].style.background = "yellow";
obj[i].children[0].style.color = "red"
}, true)
//
obj[i].addEventListener('mouseleave', function () {
obj[i].style.background = "white";
obj[i].children[0].style.color = "rgb(12,31,22)";
}, true)
}
jun(i);
}
or
var obj = document.getElementsByClassName("page_numbers")
for (i in obj) {
console.log(obj[i].children)
obj[i].style.borderColor = "rgb(85,170,255)"
function jun(i) {
obj[i].addEventListener('mouseenter', function () {
obj[i].style.background = "yellow";
obj[i].style.color = "red"
}, true)
//
obj[i].addEventListener('mouseleave', function () {
obj[i].style.background = "white";
obj[i].style.color = "rgb(12,31,22)";
}, true)
}
jun(i);
}
but as I indicated all this should really be in CSS
You trying to change color of a instead of span
Try like this
obj[i].children[0].style.color = "red"
JSFIDDLE

Categories

Resources