Retrieve CSS property value through javascript - javascript

Currently i'd like to read out the background color of a css through javascript to update a canvas with the desired color. So far i get it to work by creating a dummy object within html that holds that css from which i can read it:
The CSS content:
.logmessage-debug {
color: #fff;
background-color: #999999;
}
.logmessage-info {
color: #fff;
background-color: #5cb85c;
}
.logmessage-warn {
color: #fff;
background-color: #f0ad4e;
}
.logmessage-error {
color: #fff;
background-color: #d9534f;
}
.logmessage-fatal {
color: #fff;
background-color: #d955d9;
}
The HTML part:
<canvas id="myCanvas" width="200" height="200"></canvas>
<!-- The dummy objects allowing access to the css properties -->
<div id="debug" class="logmessage-debug"></div>
<div id="info" class="logmessage-info"></div>
<div id="warn" class="logmessage-warn"></div>
<div id="error" class="logmessage-error"></div>
<div id="fatal" class="logmessage-fatal"></div>
<script type="text/javascript">
updateCanvas();
</script>
The JavaScript part:
function updateCanvas() {
$.ajax({
url: "api/myWebService",
success: function (severityLevel) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = getSeverityColorFromStyle(severityLevel);
ctx.fillRect(0, 0, c.clientWidth, c.clientHeight);
},
complete: function() {
setTimeout(updateCanvas, 2000);
}
})
}
function getSeverityColorFromStyle(styleName) {
// Any other way to read the css background color
// directly instead of asking the dummy object?
return $("#" + styleName).css("background-color");
}
So far the above way works as expected and i can get out the desired colors i like. But I'm feeling uncomfortable by adding these dummy objects just to get access to the needed css values. Exists there any direct way to retrieve these values out of the css?

You could create a function that loops through all the stylesheets/rules on your page and tries to match it
function getStyle(className) {
var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules
for(var x=0;x<classes.length;x++) {
if(classes[x].selectorText==className) {
return (classes[x].cssText) ? classes[x].cssText : classes[x].style.cssText;
}
}
}
See this previous post for more detail How do you read CSS rule values with JavaScript?

If you know the position of the Rule or the Sheet it is in, you can easily get it via the related CSSStyleSheet, e.g.
<style id="foo">/* etc */</style>
Then
function getSeverityColorFromStyle(kwd) {
var i, rules = document.getElementById('foo').sheet.rules;
kwd = '.logmessage-' + kwd;
for (i = rules.length; i--;) // find in sheet's rules
if (rules[i].selectorText.indexOf(kwd) !== -1) // found
return rules[i].style.backgroundColor;
return '';
}
Accessing the style of a CSSStyleRule enables you to let the browser parse the cssText.
If you don't know the sheet, you may want to do another loop over document.styleSheets

var theColor = $('.class').css('background-color');

So as it seems there exists no such simple way to access a css style like accessing an existing element within the document.
At the end i decided to take the answers from Paul and JBB and (hopefully) improved them a little bit. I iterate once over all available rules within all available style sheets and push the interesting things into my own cache object. Within the getSeverityColorFromStyle() method i then try to get the matching color out of it.
var logLevelColors;
function updateCanvas() {
if(logLevelColors == undefined)
initializeLogLevelColors();
$.ajax({
url: "api/myWebService",
success: function (severityName) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = getSeverityColorFrom(severityName);
ctx.fillRect(0, 0, c.clientWidth, c.clientHeight);
},
complete: function() {
setTimeout(updateCanvas, 2000);
}
})
}
function initializeLogLevelColors() {
logLevelColors = new Object();
var logMessageIdentifier = '.logmessage-';
$.each(document.styleSheets, function (_, styleSheet) {
$.each(styleSheet.rules, function (_, rule) {
if (rule.selectorText.indexOf(logMessageIdentifier) == 0) {
var logLevel = rule.selectorText.substring(logMessageIdentifier.length);
var color = rule.style.backgroundColor;
logLevelColors[logLevel] = color;
}
})
})
}
function getSeverityColorFrom(severityName) {
var undefinedColor = 'rgba(0, 0, 0, 0.00)';
if (logLevelColors == undefined)
return undefinedColor;
return logLevelColors[severityName]
|| undefinedColor;
}

How about setting the css class directly to canvas?
Something like: <canvas id="myCanvas" class="error"></canvas>, and then you could actually get the computed style of the canvas, and update the elements inside.
var canvas = document.getElementById("canvas"), styles = getComputedStyle(canvas);
//log the properties
console.log(styles.color, styles.backgroundColor);

<script type="text/javascript">
var myText = document.getElementById("text");
alert(myText.style.display);
alert(myText.style.color);
...etc
</script>

Related

CSS Toggle Switch to add a class to a DIV with local storage

I'm trying to create a simple toggle switch to add a new class to the body tag. By default the page is red. By clicking the button the page is toggled between red and blue.
Here's the code I have so far - the Switch Colour button would then change the body class tag to blue
<body>
<p>Click the button to change the colour of page</p>
<button onclick="myFunction()">Change background colour</button>
<script>
function myFunction() {
var element = document.body;
element.classList.toggle("blue");
}
</script>
</body>
The CSS bit
body {
background-color: red;
color: white;
}
body.blue {
background-color: blue;
}
The bit I'm struggling with is to keep the settings when I refresh the page or move to another page. Is there a way to store this via Local Storage and javascript?
Thanks in advance,
Brian
For a more dynamic solution (what happens if you have more than two colors?), I would instead go with a CSS variable, where the default color is red. Stack Overflow doesn't allow reading from localStorage, so I will comment out that code, and instead use a variable for demo purposes.
I do think the code is self-explanatory.
const BACKGROUND_KEY = 'background';
var forDemoPurposeOnly = '';
function myFunction() {
let isBlue = readFromLocalStorage(BACKGROUND_KEY) == 'blue';
let color = (isBlue) ? 'red' : 'blue';
setBackgroundColor(color);
}
function setBackgroundColor(color) {
let root = document.documentElement;
root.style.setProperty('--user-selected-background', color);
setInLocalStorage(BACKGROUND_KEY, color);
}
function readFromLocalStorage(key) {
return forDemoPurposeOnly;
// return localStorage.getItem(key);
}
function setInLocalStorage(key, value) {
forDemoPurposeOnly = value;
// localStorage.setItem(key, value);
}
:root {
--background-color: var(--user-selected-background, red); /* defaults to 'red' */
}
body {
background-color: var(--background-color);
}
<body onload="setBackgroundColor(readFromLocalStorage('background'))">
<p>Click the button to change the colour of page</p>
<button onclick="myFunction()">Change background colour</button>
</body>
The local storage API is super simple to use. localStorage is available as a global in the browser, you can store a string value with a key and then retrieve the value with the key.
function myFunction() {
var element = document.body;
element.classList.toggle("blue");
var background = localStorage.getItem('background')
if (background === 'blue') {
localStorage.setItem('background', 'red')
} else {
localStorage.setItem('background', 'blue')
}
}
(function() {
var background = localStorage.getItem('background')
if (background === 'blue') {
document.body.classList.add(background)
}
})()

Add image to screen on-click and allow it to be draggable/rotatable

I am trying to create a sort of map builder where the user can select from a list of predefined objects, and upon clicking one of them, it will appear inside a frame with orientation options (dragging, rotating, resizing).
I don't understand how one can add functionality to an object that is undefined at the page's run time.
I have found a lot of good examples demonstrating how to use Jquery UI as well as adding an image to the screen onclick, but have never seen the two married together.
Here is a good example of the add onclick feature: Add image to page onclick
(Orientation on click examples are quite numerous)
Here is the code I liked from the link (from tjarratt), so if someone could help me branch off from here that would be easiest.
<html>
<head>
<script type="text/javascript">
function addimage() {
var img = document.createElement("img");
img.src = "http://bricksplayground.webs.com/brick.PNG";
img.height = 50;
img.width = 100;
//optionally set a css class on the image
var class_name = "foo";
img.setAttribute("class", class_name);
document.body.appendChild(img);
}
</script>
</head>
<body>
<button onclick="addimage();">Click</button>
</body>
</html>
Here is an example that may help you out. Consider the following code.
$(function() {
function addImage(u, c, t) {
/***
Input: URL, Class, Target Object
Output: jQuery Object of IMG element
***/
if (u == undefined) {
u = "https://bricksplayground.webs.com/brick.PNG";
}
if (c == undefined) {
c == "";
}
if (t == undefined) {
t = $("#zone");
}
var img = $("<img>", {
src: u,
class: c,
}).css({
width: "50px",
height: "100px"
});
img.appendTo(t);
return img;
}
function makeDrag(o) {
/***
Input: jQuery Object
Output: null
***/
o.draggable({
containment: "parent"
});
}
$("#add-object").click(function() {
makeDrag(addImage("https://png.pngtree.com/png_detail/20181008/red-brick-wall-png-clipart_1564742.png", "foo"));
});
});
#zone {
width: 300px;
height: 200px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<button id="add-object">Add Object</button>
<div id="zone"></div>
When 'Add Object' is clicked, an Image element is created with specific attributes. I added some defaults so if you call, addImage(), it will still add an image. You can also specify your own URL, Class, and Target Object.
Hope this helps.

Javascript/ I am stuck with changing back to the original background

I am learning JavaScript and am now doing a homework assignment.
I need to find how to remve a background image from an element after the mouse leaves the element.
I wrote the function code, Dogimgleave(), and it does not update the HTML.
Here is the code, please help me...
<img class=size src = "Images/Dog.jpg" alt="Dog!" onmouseover="Dogimgon()" onmouseleave="Dogimgleave()">
function Dogimgon(){
document.getElementById("centertext").style.backgroundImage="url('Images/Dog.jpg')";
}
function Dogimgleave() {
document.getElementById("centertext").style.backgroundColor="#65F0B6";
}
You're leaving the background image set as an image, so you won't see the background colour. You can clear the image like this...
function Dogimgleave() {
var ct = document.getElementById("centertext");
ct.style.backgroundImage = ""; // this removes the background image
ct.style.backgroundColor="#65F0B6";
}
If you set the backogrund-image and background-color simultaneously one will cover the other one. You should have only one of them set at any time:
var elem = document.getElementById("centertext");
function Dogimgon(){
elem.style.backgroundImage = "url('Images/Dog.jpg')";
elem.style.backgroundColor = "";
}
function Dogimgleave() {
elem.style.backgroundImage = "";
elem.style.backgroundColor = "#65F0B6";
}
This can be of course simplified to setting just the background property:
var elem = document.getElementById("centertext");
function Dogimgon(){
elem.style.background = "url('Images/Dog.jpg')";
}
function Dogimgleave() {
elem.style.background = "#65F0B6";
}
Or alternatively you may have color always set (it would be visible through transparent parts of the image however) and alter only the image:
var elem = document.getElementById("centertext");
elem.style.backgroundColor = "#65F0B6";
function Dogimgon(){
elem.style.backgroundImage = "url('Images/Dog.jpg')";
}
function Dogimgleave() {
elem.style.backgroundImage = "";
}
By the way, unless you task is to do that exactly in JavaScript, you may easily achieave the same result with pure CSS:
#centertext {
background: #65f0B6;
}
#centertext:hover {
background: url('/Images/Dog.jpg');
}

Call a JavaScript preload() function?

If I check a radio button for the first time I'm getting a short freezing.
Checking them a second time everything runs super smooth. I think because they are now in the browser-cache. Any chance of a preload here?
var insideMap1 = THREE.ImageUtils.loadTexture( 'insideMap1.jpg' );
var insideMap2 = THREE.ImageUtils.loadTexture( 'insideMap2.jpg' );
var insideMap3 = THREE.ImageUtils.loadTexture( 'insideMap3.jpg' );
$("input[name='opt1']").change(function() {
if ($("#radio1").is(":checked")) {
material[ "inside" ].map = insideMap1;
}
if ($("#radio2").is(":checked")) {
material[ "inside" ].map = insideMap2;
}
if ($("#radio3").is(":checked")) {
material[ "inside" ].map = insideMap3;
}
});
Use THREE.Cache:
<script>
$(document).ready(function() {
THREE.Cache.enabled = true;
var url = '/img/DSC03537.JPG';
var newImg = document.createElement('img');
newImg.src = url;
THREE.Cache.add(url, newImg);
// main program part
var insideMap2 = THREE.ImageUtils.loadTexture(url);
$("#testBox").change(function () {
$("#tstImg").map = insideMap2;
});
});
</script>
Notice: THREE.ImageUtils.loadTexture is being deprecated. Use THREE.TextureLoader() instead.
You are trying to offset the fact that loadTexture() is asynchronous, by adding a setTimeout() function in your code. But what if the loading takes 501ms? you will not see anything. You need to redesign your code so that the textures are available when they are needed. Use a TextureLoader() manager.
EDIT:
Loading of images and models are asynchronous nonblocking activities. THREE.LoadingManager() class manages asynchronous loading by keeping track of loaded and pending data. An instance of THREE.LoadingManager() can manage multiple asynchronous loaders by calling onProgress() for each item loaded and the onLoad() method after all pending loading is complete.
Documentation at: http://threejs.org/docs/#Reference/Loaders/LoadingManager
r73
Here is a way to solve your problem, This is how I use to preload images. I use to show a loader while preloading images. You need to add a preloader div in body with some css, and use following jQuery script to implement the preloader.
html:
<div class="preloader">Loading...</div>
css:
.preloader{
width: 100%;
z-index: 999999;
display: inline-block;
background-color: #f2f2f2;
text-align: center;
font-size: 40px;
}
javascript:
$(function(){
$('.preloader').css('height',window.innerHeight);
$('.preloader').css('padding-top',(window.innerHeight/2)+"px");
preload_images(
[ /* image list to be preloaded */
'http://weknowyourdreams.com/images/sunset/sunset-02.jpg',
'http://cdn.bigbangfish.com/beautiful/beautiful-sunset/beautiful-sunset-12.jpg',
'http://cdn.bigbangfish.com/beautiful/beautiful-sunset/beautiful-sunset-6.jpg'
],
function() { /* callback */
$(".preloader").slideUp("slow");
}
);
});
function preload_images(a, callback) {
var l = a.length;
0 === l && callback();
var i = 0;
$(a).each(function() {
$("<img>").attr("src", this).load(function() {
i++, i === l && callback();
})
});
return false;
}
JSFIDDLE

onmouseover function Javascript for changing the background of a section

I was trying to write a function that changes the color of background of a section by going over it with the mouse - using 'onmouseover'. I was looking for similar question and tried the solutions that was offered but it did not work on my code.
Here is what i did:
function Rectangle(count){
var newRec = document.createElement("SECTION");
newRec.style.width="202px";
newRec.style.height="312px";
newRec.style.border="1px solid #3f3f3f";
newRec.style.background = "#FFFFFF";
newRec.style.display = "inline-block";
newRec.style.margin= "44px";
newRec.style.size= "50px";
var appendRec = function() {
document.addEventListener("onmouseover", myFunction);
document.getElementsByTagName('main')[0].appendChild(newRec);
};
function myFunction() {
document.getElementTagName("SECTION").style.background = "#000000";
};
appendRec();
};
Can anyone tell me what i did wrong?
And I was trying to work with the console but this code doesn't say anything is wrong...
document.getElementTagName("SECTION").style.background = "#000000"; is wrong.
First, it's called getElementsByTagName(). And second, it returns an array, not just one element.
Solution: Give the <section> an id and use getElementById() instead.
You just need
document.getElementById('WhichElementWillBeHoveredID').onmouseenter = function() {
// when entering element...
}
document.getElementById('WhichElementWillBeHoveredID').onmouseleave = function() {
// when leaving element
}
Sure... you can easily use CSS as well..
SELECTOR:hover { background-color: #444 }
I created a fiddle to change background color and this is the only requirenment then I think it is good
http://jsbin.com/cagawa/edit?html,css,output
#mydiv{
background: #cccccc;
}
#mydiv:hover{
background: #ffdd00;
}
try change
var appendRec = function() {
document.addEventListener("onmouseover", myFunction);
document.getElementsByTagName('main')[0].appendChild(newRec);
};
to
var appendRec = function() {
document.getElementsByTagName('main')[0].appendChild(newRec);
newRec.addEventListener("mouseover", myFunction);
};
I edited littlebit code, try now :)
If im not wrong on line 12:
document.addEventListener("onmouseover", myFunction);
should be replaced by
document.addEventListener("onmouseover",myFunction());

Categories