Change background color at runtime - javascript

I would like to be able to change the color of a gridbox at runtime based on the text in the box. I have a JS function called checkColor(str) which will return a color but I can't figure out the correct syntax to get it to work.
<div class="grid-item" style="background-color:checkColor(Swim)">
{{bunk.activities[_-1]}}
</div>
<script>
function checkColor(s){
if (s == "Swim"){
return 'red'
}
}
</script>

There is no CSS syntax for calling a JavaScript function. You need to approach this from the JavaScript end.
Possibly you should set up a DOM Ready event listener which will get all the divs you care about and then loop over them accessing their style properties to set the colour you want. Since you would need to get "Swim" from somewhere you might want to use a data attribute.
That said, it would probably better to just forget about JS entirely for this and use a class instead.
class="grid-item swim">
and
.grid-item.swim { background-color: red; }

Well, you can not add js function in style attribute! Instead, you need to change the background using JavaScript & CSS:
var element = document.getElementById("item_1");
element.classList.add("swim");
.swim{
background-color: red;
}
<div id="item_1" class="grid-item">
Hello World
</div>
Above we injected a class name 'swim' that has a style of red background.

You can do it this way, if you set the value to check as "data-value".
Loop all elements with class grid-item, if "data-value" == Swim apply color.
function checkColor(s,item){
if (s == "Swim"){
item.style.backgroundColor = "red";
}
}
var item = document.getElementsByClassName('grid-item')
for (var i in item){
checkColor(item[i].getAttribute('data-value'),item[i])
}
<div class="grid-item" data-value="Swim">
{{bunk.activities[_-1]}}
</div>
<div class="grid-item" data-value="Swim">
{{bunk.activities[_-1]}}
</div>

`function checkColor(s){
if (s == "Swim"){
return 'red'
}
}
document.getElementsByClassName('grid-item').style.background = checkColor("Swim");
`
This should set "grid-item"'s background to red

you cant call java script function from CSS rather than that i suggest to you to use java script and make switch with all colors and item names.
function checkColor(){
var elements = document.getElementsByClassName();
for(var x = 0;x < elements.length;x++){
switch(elements[x].innerHtml){
case 'swim':{
elements[x].style.background = 'red';
break;
}
.
.
.
.
}
}
}

Related

Change color of all elements in class on click JavaScript

I have an image (SVG) of a human body. I would like to use JavaScript so that when I click a particular area (say, the lower leg) then all of the elements with the class "lower-leg" (even if not clicked) have their color changed -- this makes it much easier for the user.
Here is the JavaScript I currently have:
function changeclassstyle() {
var c = document.getElementsByClassName("lower-leg");
for (var i=0; i<c.length; i++) {
c[i].style.fill = "red";
}
}
The problem with this code is that it is only generalized for "lower-leg". I may have over a dozen classes I would like this to work for and don't think it is efficient to write 12 functions with the only change being the class name. Is there a way to grab what class was selected and then input that in the function?
--
Additionally, I would love to figure out how, once that section of the body is selected, I can store the class name. I would, in the end, want to store the selection, along with other inputted information in a database. But, this may be for a future question unless someone can help!
Here's how I would do it (tested on a couple of div's).
What we're doing is passing the event object to the event handler (your changeclassstyle() function). It then uses the class of the clicked-on item (the event target's class) and changes everything else on that page with that same class name to use your new desired CSS style.
function changeclassstyle(e) {
// Get all items that have the same class as the item that was clicked
var limbs = document.getElementsByClassName(e.target.className); // for div's and the like
// var limbs = document.getElementsByClassName(e.target.className.baseVal); // turns out this is needed for SVG items
// "limbs" is an HTMLCollection, not an array, so functions like .foreach won't work; C-style for-loops or modern for/let/of loops are better
for (let item of limbs) {
item.style.backgroundColor = 'red';
// item.style.fill = 'red'; // This is probably what you need for your SVG items
}
// You could still use your C-style for loop if needed/wanted
/*
for (var i=0; i<limbs.length; i++) {
limbs[i].style.fill = "red";
}
*/
}
The onchange call looks like this (using my div as the example):
<div class="upper-arm" onclick="changeclassstyle(event)">
</div>
<div class="lower-leg" onclick="changeclassstyle(event)">
</div>
The whole example with simple div's.
<html>
<head><title>stuff</title></head>
<body>
<script type="text/javascript">
function changeclassstyle(e) {
// For debugging. You may want to expand 'e' here in your browser's debug tools if you're not seeing the values you need/want
console.log(e)
var limbs = document.getElementsByClassName(e.target.className.baseVal);
for (let item of limbs) {
item.style.backgroundColor = 'red';
}
}
</script>
<style type="text/css">
div {
height: 100px;
width: 100px;
background-color: 'white';
border: 1px solid black;
}
</style>
<div class="upper-arm" onclick="changeclassstyle(event)">
</div>
<div class="upper-arm" onclick="changeclassstyle(event)">
</div>
<div class="upper-arm" onclick="changeclassstyle(event)">
</div>
<div class="lower-leg" onclick="changeclassstyle(event)">
</div>
<div class="lower-leg" onclick="changeclassstyle(event)">
</div>
<div class="lower-leg" onclick="changeclassstyle(event)">
</div>
</body>
</html>
You can use parameters in function where you pass class and color like below
function changeStyle(cls,clr) {
let elems = document.getElementsByClassName(cls);
if(!elems) return;
for (let elem of elems) {
elem.style.color = clr;
}
}
As per the iteration of many classes like i said you can store classes in array and iterate each of them.
let classes = ['one','two','three','four'];
classes.forEach(function (cls) {
changeStyle(cls,"red");
});
You can play with fiddle here if you want to test/experiment: https://jsfiddle.net/thrL5uqw/8/
Note: Change style property as you wish, For now i have used color for demo
I'm a bit late to the party, but here's my take on the problem.
Like the others told you, you'll need to use an additional parameter to your function to specify the class you want to modify your elements (or try to figure out the class from the clicked element), therefore you should have something like that:
/**
* This function will handle the click event on one of the part of the SVG.
* #param {string} lClass This the class of the element to modify
*/
function handleClick(lClass) {
for (let e of document.getElementsByClassName(lClass)) {
// Here you can do all the changes you need on the SVG element.
e.style.fill = "red";
}
}
And when it comes to the event binding, you could do like the other suggested and add the onclick event binding propery on the HTML Element, or you could bind it in you JS with the addEventListener function (that way you don't have to repeat the onclick property on each of your SVG elements).
// For each element of all the listed class, bind the "click" event to the handleClick function
const listenClass = [/*List of your classes*/];
for (let l of listenClass) {
for (let e of document.getElementsByClassName(l)) {
e.addEventListener('click', handleClick.bind(this, l));
}
}
Demo: https://plnkr.co/edit/gay2yBaVi5QD868fsTa6?p=preview
I hope it helped.

How do I change an attribute or class using only Javascript?

I would like to change the styling attribute values of all elements that have the class "post-feature" and contain an attribute value of "http"
So the div element will look like the following:
<div class="post-feature" style="backgroundimage:url(http://local.test.com/test_image.jpg);">
So far the http check works. But I am not able to set the attribute value.
I have the following code
var features = document.getElementsByClassName(".post-feature")
[0].getAttribute("style");
if (features.includes("http")) {
features.setAttribute("background-color", "orange");
} else {
alert('no change');
}
You can use querySelectorAll('.post-feature[style*="http"]') to find those elements.
Then simply iterate through them and i.e. set their background color with
element.style.backgroundColor = 'orange';
Now, if you want to make sure you only target elements having a background-image and http, you can use this selector:
querySelectorAll('.post-feature[style*="http"][style*="background-image"]')
Also, by adding an i (or I) just before the end bracket [style*="http"i], the value will be compared case-insensitively.
window.addEventListener('load', function() {
var elements = document.querySelectorAll('.post-feature[style*="http"]');
for (var i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = 'orange'; /* add propert value */
/* replace class
elements[i].className = 'myClass';
*/
/* add a class
elements[i].classList.add('myClass');
*/
}
/* temp log */
console.log('Found ', elements.length,' element(s)');
})
div {
height: 40px;
background-color: gray;
}
div + div {
margin-top: 10px;
}
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature"></div>
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature"></div>
Updated
To only change styling, like colors etc., you don't even need a script, you can use CSS alone
div {
height: 40px;
background-color: gray;
}
div + div {
margin-top: 10px;
}
/* for elements that contain "http" and "background-image" */
.post-feature[style*="http"i][style*="background-image"i] {
background-color: orange;
}
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature"></div>
<div class="post-feature" style="background-image:url(HTTP://local.test.com/test_image.jpg);"></div>
<div class="post-feature"></div>
As a note, and as discussed in a few comments, if to make sure it is the background-image property that also contain the http in its url(), you can adjust the selector to this, which as well can be used without any script, as a CSS rule
.post-feature[style*="background-image:url(http"i] {
background-color: orange;
}
The above selector can of course also be used in the first sample, like this
querySelectorAll('.post-feature[style*="background-image:url(http"i]')
First, you can use querySelctorAll() with a CSS query that selects the elements with the class you desire and, in most cases, you should use this instead of getElementsByClassName() as that returns a "live node list" that causes the DOM to be re-scanned every time you access it.
Next, setAttribute() is for setting HTML element attributes. You are asking to change the value of a CSS property. While that could be accomplished with setAttribute('style', value), it is very "old-school" and not the best approach, nor is getAttribute('style') the best way to read a CSS property value (it won't work if the CSS was set from a style sheet).
Also, your code is trying to access: backgroundimage, but the property is accessed as background-image when working in CSS and backgroundImage when accessing it via JavaScript.
To access the inline styles applied to an HTML element, just access the style property of that element, followed by the name of the CSS property you are interested in. For example:
var bColor = element.style.backgroundColor;
If the style has been applied to the element from an internal style sheet or an external style sheet, the above approach won't work for you and you'll need to get it another way, via window.getComputedStyle():
var bColor = window.getComputedStyle(element, null).backgroundColor;
But, note that getComputedStyle() doesn't always return the same value that you set - - it's the value after the browser has computed all factors. In this case, even paths that you wrote as relative references (without the "http") will be returned as absolute paths (with the http).
So, here is a modern approach that correctly checks only the background-image CSS property for the presence of http.
NOTE: This solution tests for http specifically in the background-image property. Unlike most of the other answers given, this code will correctly ignore http in other CSS properties besides background-image. Examine the CSS of the last div to see this in action.
// querySelectorAll() is more efficient than getElementsByClassName()
var features = document.querySelectorAll(".post-feature");
// Loop over the list
for(var i = 0; i < features.length; i++){
// Get access to the background-image property (called backgroundImage from JavaScript) value,
// convert that value to lower case and check to see if "http" is in that value
if(features[i].style.backgroundImage.toLowerCase().indexOf("http") > -1){
// Set the CSS background-color property (called "backgroundColor" in JavaScript) to orange:
features[i].style.backgroundColor = "orange";
// Just for testing:
features[i].textContent = features[i].style.backgroundImage;
} else {
alert("No change");
}
}
.post-feature { width:100%; height:50px; border:1px solid black; background-color:gray; color:yellow; }
<!-- The correct CSS property is "background-image", not "backgroundimage" -->
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature" style="background-image:url(test_image.jpg);"></div>
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature"
style="border-image: url('http:///images/border.png') 30 30 repeat;background-image:url(test_image.jpg);">I have "http" in one of my CSS properties, but not "background-image", so I shouldn't be orange.</div>
i think some wrong in your code, try this code
element.setAttribute("style", "background-color: orange;"); // bad
or
element.style.backgroundColor = "orange"; // good
Use element.style.backgroundColor and indexOf
var features = document.getElementsByClassName(".post-feature")[0].getAttribute("style");
if (features.indexOf("http") > -1) {
features.style.backgroundColor = "orange";
} else {
alert('no change');
}
check this fiddle
https://jsfiddle.net/vywk72j8/2/
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);">
tt</div>
var feature = document.getElementsByClassName("post-feature")[0];
if (feature.style.backgroundImage.indexOf("http") !== -1) {
feature.style.backgroundColor = "orange";
} else {
alert('no change');
}
In your code, you are fetching the attribute value in features
var features = document.getElementsByClassName(".post-feature")
[0].getAttribute("style");
Here features is a string containing attribute value, not an element so you cannot use it to set value.

Changing properties of all <hr> html elements

In css I have set all the <hr> elements in my html to "display:none;" which works.
I have an onclick event listener set up to change the "display" to "block".
I use:
document.getElementsByTagName("hr").innerHTML.style.display = "block";
I get an error "Cannot read property 'style' of undefined".
Do it the following way:
var hrItems = document.getElementsByTagName("hr");
for(var i = 0; i < hrItems.length; i++) {
hrItems[i].style.display = 'block';
}
This is incorrect in two ways
getElementsByTagName gives you a list on elements and there is no method to operate on all elements, so you'll have to loop through all of them and add the required style individually.
innerHTML returns a string containing the mark up in an element but <hr> doesn't have any thing in it and the style property is on the <hr> itself.
var hrs = document.getElementsByTagName("hr");
for(var i = 0; i < hrs.length; i++) {
hrs[i].style.display = 'block';
}
Simple (and very effective) solution:
tag your body with a class-element
<body class="no_hr"> <article><hr/> TEXT Foo</article> <hr/> </body>
in css don't hide hr directly, but do
.no_hr hr {
display:none;
}
now define a second style in your css
.block_hr hr{
display:block;
}
in your buttons onClick, change the one and only body class from no_hr to block_hr
onclick() {
if ( document.body.className == "no_hr" ) {
document.body.className = "block_hr";
} else {
document.body.className = "no_hr";
}
}
This is a very charming solution, because you don't have to iterate over elements yourself, but let your browsers optimized procedures do their job.
For people who want a solution that doesn't require JavaScript.
Create an invisible checkbox at the top of the document and make sure that people can click on it.
<input type="checkbox" id="ruler"/>
<label for="ruler">Click to show or hide the rules</label>
Then tell the stylesheet that the <hr>s should be hidden by default, but should be visible if the checkbox is checked.
#ruler, hr {display:none}
#ruler:checked ~ hr {display:block}
Done. See fiddle.
getElementsByTagName() returns a node list, and therefore you must iterate through all the results. Additionally, there is no innerHTML property of an <hr> tag, and the style must be set directly on the tag.
I like writing these types of iterations using Array.forEach() and call:
[].forEach.call(document.getElementsByTagName("hr"), function(item) {
item.style.display = "block";
});
Or, make it even easier on yourself and use jQuery:
$("hr").show();

Change CSS On Hover

I try to make each of them separated.
<div id="a" onmouseover="chbg('red')" onmouseout="chbg('white')">This will change b element</div>
<div id="b">This is element b</div>
<div id="f" onmouseover="chbg('blue')" onmouseout="chbg('white')">This will change g element</div>
<div id="g">This is element g</div>
<div id="j" onmouseover="chbg('yellow')" onmouseout="chbg('white')">This will change k element</div>
<div id="k">This is element k</div>
Here is JS
function chbg(color) {
document.getElementById('b').style.backgroundColor = color;
document.getElementById('g').style.backgroundColor = color;
document.getElementById('k').style.backgroundColor = color;
}
Doesn't work properly here http://jsfiddle.net/qUzn5/ .
You might want to put a second argument in your function like this:
JavaScript:
function chbg(color, id) {
document.getElementById(id).style.backgroundColor = color;
}
HTML:(Repeat the div's)
<div id="a" onmouseover="chbg('red', 'a')" onmouseout="chbg('white')">This will change b element</div>
Currently they all get colored because the function calls each of the ids
I guess you should add a variable to your javascript function. This variable contains the id of the element to be changed.
I do not know anything of javascript, but i guess it should look like this:
function chbg(id,color) {
document.getElementById(id).style.backgroundColor = color;
}
You tagged this with jQuery so I'm going to assume you're using that. If so, cut down your code a bit like this...
$('#b').css('background-color', color);
If you're using jquery you shouldn't need to use getElementById and .style.
http://api.jquery.com/css/#css2
And since your function has everything in it, each background will change.
If you must use javascript instead of CSS, try passing a different argument to your function. Perhaps the ID of the background that should change. Then set conditionals in your function according to what ID is passed.
if ( divId == 'b ) {
Code to change b div
}

When one is clicked, disable the other

So I have a mini slide menu in my website there is a menu you can choose what you want to read. There are points to click, when u clicked it the point get a red background.
But there is a problem.
When i click one point and then an other point the first clicked point have to lose his background.
Here is my HTML:
<div id="slide_button" onClick="clicked(this);"><dir class="button_1"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_2"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_3"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_4"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_5"></dir></div>
Here is my JS:
function clicked(slide_button) {
slide_button.getElementsByTagName("dir")[0].style.backgroundColor="red";
}
HERE IS AN EXAMPLE ON FIDDLE.
My "QUESTION IS" what i have to do to solve that?
What should I pay attention?
First you need to fix your HTML becaue your id values aren't unique. In fact, you don't even need id values, so you should use "slide_button" as a class. You can then use it to select all the buttons:
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
The CSS needs to be changed now so "slide_button" is a class selector, instead of an id selector:
.slide_button {
display: inline-block;
}
As for clearing the background, clear all of them before coloring the selected one red:
function clicked(slide_button) {
var buttons = document.getElementsByClassName('slide_button');
for(var i = 0; i < buttons.length; i++) {
buttons[i].getElementsByTagName('dir')[0].style.backgroundColor = '';
}
slide_button.getElementsByTagName('dir')[0].style.backgroundColor = 'red';
}
jsfiddle
This uses just JavaScript with no JQuery, but if you are using JQuery, you might as well use it here. The code is a lot shorter and easier to follow.
Here's a JQuery version:
$(function() {
$('.slide_button').click(function() {
var $button = $(this);
$button.children(':first').css({ backgroundColor: 'red' });
$button.siblings().children(':first').css({ backgroundColor: '' });
});
});
Note: This registers a click-handler, so you can get rid of the "onclick" attirbutes.
jsfiddle
You have to select all other points and set their background to none.
Or remeber which point is selected and on select another just remove background on last and remeber current point, then set its background to red.
See fiddle: http://fiddle.jshell.net/399Dm/5/
At first id should be unique per element.
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
Second, you should store reference of clicked element if you want later remove background color, and instead of inline event handlers or binding all elements would be better if you use event delegation.
Demonstration
(function () {
"use strict";
// getting parent node of divs, due to bind click event. then
var ele = document.querySelector(".slide_button").parentNode,
prev = null; // store previous clicked element
ele.addEventListener("click", clickHandler); // event handler.
function clickHandler(e) {
var t = e.target; // get target of clicked element
// filter by target node name and class. edit: removed class checking
if (t.nodeName.toLowerCase() === "dir") {
// checking value of prev !== null and it's not same element.
if (prev && prev !== t) {
prev.style.backgroundColor = "";
}
prev = t; // store clicked element
t.style.backgroundColor = "red";
}
}
}());
I have fixed the fiddle so that it works hopefully as you plan.
http://jsfiddle.net/399Dm/8/ There you go!
var forEach = function(ctn, callback){
return Array.prototype.forEach.call(ctn, callback);
}
function clear(element, index, array) {
element.getElementsByTagName("dir")[0].style.backgroundColor="";
}
function clicked(slide_button) {
forEach(document.getElementsByClassName("slide_button"), clear);
//.style.backgroundColor="";
slide_button.getElementsByTagName("dir")[0].style.backgroundColor="red";
}
I had a slightly different method than #atlavis but a similar result.
http://fiddle.jshell.net/2AGJQ/
JSFIDDLE DEMO
jQuery
$('.slide_button').click(function(){
$('.slide_button dir').css("background-color", "inherit");
$(this).find('dir').css("background-color", "red");
});
HTML - Your markup is invalid because you have duplicate ids. Make them classes as below instead.
<div class="slide_button" >
<dir class="button_1"></dir>
</div>
<div class="slide_button">
<dir class="button_2"></dir>
</div>
<div class="slide_button">
<dir class="button_3"></dir>
</div>
<div class="slide_button">
<dir class="button_4"></dir>
</div>
<div class="slide_button">
<dir class="button_5"></dir>
</div>
CSS change
.slide_button {
display: inline-block;
}
If you can look at the following jsfiddle, I used jQuery to get what you want.

Categories