How to temporarily add a CSS style? - javascript

I have a div and when I mouse over it I want to change the background (and possibly other properties). I can do it by calling el.style.backcolor = "", but is there a way I can add another CSS style to it then remove it later? Like style += mouseOverStyle and then style -= mouseOverStyle. That way I could select the properties to change in the CSS instead of in the JavaScript code.
EDIT: I may want to apply the new style in other situations, not just mouseover, so #div:hover isn't really a general solution. What I'm really asking is is there something like style.add("style") and style.remove("style")?

If I understood you correctly, you're asking to change the background when you hover your div element?
This is easily done via CSS, no Javascript or other codes are necessary!
#myDiv
{
background-color: #f00;
}
#myDiv:hover
{
background-color: #00f;
}
Of course you can change other styles too, you don't need to add another class to change one or more styles.
Hope that helps :)

Just add or remove CSS classes when needed.
Adding:
yourElement.className += ' my_class';
Removing:
yourElement.className = yourElement.className.replace(/\bmy_class\b/, '');
With jQuery you can use addClass, removeClass and toggleClass methods (see the docs).

You could try using multiple :hover pseudo selectors:
div.style1:hover { background: red }
div.style2:hover { background: yellow }
Then use javascript/jquery to switch between html class attributes

I would recomendate you to use a JS library, such as jQuery. In jQuery it is simple like that:
http://api.jquery.com/addClass/ together with the mouseover event handling http://api.jquery.com/mouseover/.

function changeStyle()
{
document.getElementById("elementID").style.color="green";
}
after the .style. you should paste the css attribute you want to edit.

If you're wanting to use js, change the properties on the user event.
onmouseover : el.style.background = "blue";
onmouseout : el.style.background = "red";
If you want to add more properties as time goes along just throw it in a function
function onMouseOverFunction () {
el.style.background = "blue";
el.style.color = "blue";
el.style.font-size= "1em";
}

Related

Create a very low specificity css property

I am trying to create a very low specificity css property using javascript. Just like !unimportant (which doesn't exists)
I don't know whether this is possible or not.
My reason to look for something like !unimportant is that I am writing a small javascript plugin. In which I want to add a default style to a element which should be later easily overriden by the user.
But if I write:
element.style.backgroundColor = "green";
The user will not be able to override the above style easily without using !important. So, I added a dynamic style tag by using the following code:
var style = document.createElement('style');
// WebKit hack :(
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
and then to the above code, I added a dynamic stylesheet using the following code:
var element = document.getElementById('main');
// To use attribute names to apply the styles
element.setAttribute('custom-el', '1');
var sheet = style.sheet;
var properties = "background-color: green;";
var elName = "[custom-el]";
if (sheet.insertRule) {
sheet.insertRule(elName + "{" + properties + "}", 0);
} else if (sheet.addRule) {
sheet.addRule(elName, properties, 0);
}
Now the background-color: green can be overriden by using the following code:
div.main {
background-color: red;
}
But as you can see in css, I used higher specificity to override background-color: green i.e div + .green.
But I want the overriden to happen even when user writes the following css:
.main{ /* Could be simple class name or id name or even tag name */
background-color: red;
}
Fiddle
This might seems to be a small issue. but it is a big problem for me. Please help.
I would simply write like this:
element.style.backgroundColor = element.style.backgroundColor || "green";
Where, if backgroundColor is undefined then it uses green as backgroundColor else it would take the backgroundColor from stylesheet.
Finally I got the answer..
document.head.insertBefore(style, document.head.children[0]);
I should just insert the dynamic stylesheet above already present stylesheets in the head tag.
Working Fiddle
Unfortunately, this is not working in any IE version. I am still looking for answer.

javascript - changing a class' style

I've been working with jQuery for a while, but now I want to write something in pure javascript and it's prooving to be challenging..
One of my biggest problems at the moment is that I haven't found a way to set/change styling for a class. This is not a problem for elements with id, but I want to change the styling for a group of elements with the same class and not just for one element with an id..
In jQuery I would just write:
$('.someClass').css('color','red')
Is there really no simple equivalence to this in pure js?
Try the following
var all = document.getElementsByClassName('someClass');
for (var i = 0; i < all.length; i++) {
all[i].style.color = 'red';
}
Note: As Cheery pointed out getElementsByClassName won't work in IE. The linked question has a nice way to work around this limitation
javascript document.getElementsByClassName compatibility with IE
I find it easier to use CSS variables. You can set the class to use a variable and then change that value in Javascript, thus changing the CSS.
If you style the class like:
:root {
--some-color: red;
}
.someClass {
color: var(--some-color);
}
Then you can change the variable's value in Javascript with
document.documentElement.style.setProperty('--some-color', '(random color)');
(random color) can then be anything that would be considered a valid CSS color (eg. blue, black, #626262, rgb(12, 93, 44))
Updating the value in JS automatically updates the page as well.
And of course, this can be done with any property, not just color. Here is an example that changes the padding of a class:
CSS
:root {
--some-padding: 12px;
}
.someClass {
padding: var(--some-padding);
}
Javascript
// Set padding to 15px
document.documentElement.style.setProperty('--some-padding', '15px');
// Set padding to 5rem
document.documentElement.style.setProperty('--some-padding', '5rem');
// Set padding to 25%
document.documentElement.style.setProperty('--some-padding', '25%');
Useful example: toggle dark / light mode:
(How to use css properties to dynamically set css properties)
// set to light mode:
document.documentElement.style.setProperty('--bg-color', getComputedStyle(document.documentElement).getPropertyValue('--bg-color-light'));
// set to dark mode:
document.documentElement.style.setProperty('--bg-color', getComputedStyle(document.documentElement).getPropertyValue('--bg-color-dark'));
With the respective css:
:root {
--bg-color: black;
--bg-color-light: white;
--bg-color-dark: black;
body {
background-color: var(--bg-color);
}
Sources
How to declare and use CSS variables: https://www.w3schools.com/css/css3_variables.asp
How to update a CSS variable in JS: https://css-tricks.com/updating-a-css-variable-with-javascript/
var sheet = document.createElement('style')
sheet.innerHTML = ".someClass {color: red;}";
document.body.appendChild(sheet);
What you want to change is the style sheet, I guess? Thats possible in Javascript, see
Quirksmode: Change CSS
Totally Pwn CSS with Javascript (in Internet Archive)
Is the only way to change a style to do it per-element in JavaScript? (possible duplicate)
I'm afraid there is no library for that, I really would like to see one...
var all = document.getElementsByClassName('someClass');
for (var i = 0; i < all.length; i++) {
all[i].className += " red";
}
For better coding style add another class to the elements with the code above and then use CSS to change the color of all elements like this:
.red {
color:red;
}
You can use selector library, for example Sizzle: http://sizzlejs.com/ but if you want pure JS that I guess you are stuck with getting all the elements, and then programatically "handpicking" the ones that have classes you are interested in using RegEx like this for example:
This is an equivalent of your JQuery oneliner:
for( i in document.all) document.all[i].className && /\bpost-text\b/g.test(document.all[i].className) && (document.all[i].style.color = "red")
:)
If you don't need it in one line you can make it faster (and much more readable):
var myClassName = "someClass";
var regexp = RegExp("\\b"+myClassName+"\\b/g");
var elements = document.all;
for( i in elements){
var this_element = elements[i];
if(regexp.test(this_element.className){
this_element.style.color = "red";
}
}
If "for( i in object)" doesn't work for you, just use classic for loop "for(var i = 0; i < elements.length; i++)".
It could be 'beautified' a bit with the use of some slightly more advanced JS concepts (array function mappings, folding and such), which JS version are you coding agains? I guess it's not ECMA Script 5, right?
Also, check out this question/answer Get All Elements in an HTML document with a specific CSS Class

Issue in Chrome, removing CSS with jQuery stays in chrome

I'm currently working on a table application heavily coded in javascript using jQuery.
When you click on a td cell jQuery pushes 2px solid black to the border property. Then on blur I remove the style attribute with removeAttr to make it revert back to the stylesheet settings. Works fine in IE9, but when I test it in Chrome, the left border resizes, but stays black.
The only thing that seems to get rid of this is opening the console. When I blur with the console open the style tag removes so I don't understand why it's still rendering a black border on the left. Any ideas?
EDIT: I've made a video showing the problem I'm experiencing.
http://www.youtube.com/watch?v=JCmYNOO5u4I
Here's the code:
$("td.display").live('mouseenter', function () {
$(this).addClass('selected');
}).live('mouseleave', function () {
$(this).removeClass('selected');
});
The CSS is:
table TD.selected {
border: 2px solid;
border-color: Black;
}
Rather than using $.removeAttr, use $.css to restore the CSS. $.removeAttr isn't going to work properly due to how CSS persists, most likely.
What you should really do is add a class on focus, then remove that class on blur. That is, $.addClass and $.removeClass, documented at the respective links.
Instead of using JavaScript to achieve this trivial effect, use CSS. The :hover pseudo-selector is well-supported in all modern browsers.
td.display:hover {
border: 2px solid black;
}
I have adjusted your selectors, since <td> elements are always contained in a <table> element.
Demo: http://jsfiddle.net/JKM7e/
Update
This is one of the many table-css-related bugs in Chrome. A work-around is to initiate a re-render. To solve the issue, let Chrome render the page again. This fix should not activate in non-webkit browsers, so an additional variable is added.
I've also optimized your code, and replaced the deprecated live with on. The new revision can be found here.
// true if webkit, false otherwise
var isWebkit = !!$('<div style="-webkit-border-radius:1px">')[0].style.cssText.length;
$(document).on('blur', 'input.editCell', function () {
var $thisParent = $(this).parent(); // <-- Optimizing by caching
// Remove Highlight and bold around cell
$thisParent.removeClass('selected');
var colRow = $thisParent.attr('id').split('_');
$('th:containsExactly(' + colRow[0] + ')').removeAttr('style');
$('td.yAxis:containsExactly(' + colRow[1] + ')').removeAttr('style');
// Change class back to display
$thisParent.attr('class', 'display');
// Take the entered value and put it in the cell
$thisParent.html(this.value);
// if(isFunction(this.value) === 'SUM')
if (isWebkit) { // Fix for Webkit bug: render the table again
// Without jQuery, for efficiency
var style = document.getElementById('spreadsheetTable').style;
style.color = '#111'; //<--1. Change style
setTimeout(function(){style.color='';}, 4); //<--2. Fix
}
});
Two options:
- instead of removeAttr, reset the style with .css()
- use a class instead, and use toggleClass() in the focus and our events
The second option is definitely preferable.

Function to remove background-images for an element and all its children via javascript

I would like to remove all CSS background images for a given element and all of its children with Javascript. This question is sort-of a spin off on another question I asked. The end goal is the same, to skin jQuery UI widgets.
I am currently using jquery/jquery-ui if any of would use these to solve the problem.
Any ideas?
bonus:
It would be wonderful to be able to remove background images for different jquery-ui states, BUT i've all but resolved myself to overriding these bg images via CSS.
EX: ui-state-hover, ui-state-active both have background images associated with them.
or
Please let me know if you think any kind of programmatic style overrides should not be done this way (please supply your reasoning).
You could just use an easy jQuery selector (might be slow though)
// You might now need the !important, but it overrules other !important's
$( '*', givenElement ).css( 'backgroundImage', '0 !important' );
But it's better to just add a certain class to your parent element, and then use normal CSS to style the children. For example:
// Javascript
$( givenElement ).addClass( 'stateX' );
// CSS, basic example to give you an idea
.stateX div, .stateX span {
background-image: 0;
}
.stateY div, .stateY span {
background-image: url( someimage.png );
}
function removeChildBackgrounds(parent) {
parent.style.backgroundImage = "none";
var childNodes = parent.childNodes;
for(var i=0;i<childNodes.length;i++) {
removeChildBackgrounds(childNodes[i]);
}
}
This would remove all backgrounds recursively, starting with the parent node.

document.body.style.backgroundImage vs document.body.background

What is the difference between the two?
document.body.background refers to the deprecated background attribute of the body tag
http://www.w3schools.com/TAGS/att_body_background.asp
document.body.style.backgroundImage refers to the CSS background-image property of the body tag. It is equivalent to something like...
body {
background-image:url('paper.gif');
}
Use the latter :-)
There's a third important entry to consider in addition to the depracated document.body.background and the way to change the CSS background image with document.body.style.backgroundImage.... You can use document.body.style.background to change all the background properties, including color image and repeat:
document.body.style.background = "red";
or, to set more than one property
document.body.style.background="#0000FF url(example.jpg) repeat-x";
The above sets a background color, a background image, and sets a horizontal repeat for that image.
This is similar to the CSS:
body {
background:#0000FF url('example.jpg') repeat-x; }
( here's a little more info about document.body.style.background at W3Schools... I'm sure there's more complete info elsewhere though )
document.body.background: You are not using CSS.
document.body.style.backgroundImage: you are setting using CSS.

Categories