Change :hover CSS properties with JavaScript - javascript

How can JavaScript change CSS :hover properties?
For example:
HTML
<table>
<tr>
<td>Hover 1</td>
<td>Hover 2</td>
</tr>
</table>
CSS
table td:hover {
background:#ff0000;
}
How can the td :hover properties be modified to, say, background:#00ff00, with JavaScript? I know I could access the style background property using JavaScript with:
document.getElementsByTagName("td").style.background="#00ff00";
But I don't know of a .style JavaScript equivalent for :hover.

Pseudo classes like :hover never refer to an element, but to any element that satisfies the conditions of the stylesheet rule. You need to edit the stylesheet rule, append a new rule, or add a new stylesheet that includes the new :hover rule.
var css = 'table td:hover{ background-color: #00ff00 }';
var style = document.createElement('style');
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
document.getElementsByTagName('head')[0].appendChild(style);

You can't change or alter the actual :hover selector through Javascript. You can, however, use mouseenter to change the style, and revert back on mouseleave (thanks, #Bryan).

Pretty old question so I figured I'll add a more modern answer. Now that CSS variables are widely supported they can be used to achieve this without the need for JS events or !important.
Taking the OP's example:
<table>
<tr>
<td>Hover 1</td>
<td>Hover 2</td>
</tr>
</table>
We can now do this in the CSS:
table td:hover {
// fallback in case we need to support older/non-supported browsers (IE, Opera mini)
background: #ff0000;
background: var(--td-background-color);
}
And add the hover state using javascript like so:
const tds = document.querySelectorAll('td');
tds.forEach((td) => {
td.style.setProperty('--td-background-color', '#00ff00');
});
Here's a working example https://codepen.io/ybentz/pen/RwPoeqb

What you can do is change the class of your object and define two classes with different hover properties. For example:
.stategood_enabled:hover { background-color:green}
.stategood_enabled { background-color:black}
.stategood_disabled:hover { background-color:red}
.stategood_disabled { background-color:black}
And this I found on:
Change an element's class with JavaScript
function changeClass(object,oldClass,newClass)
{
// remove:
//object.className = object.className.replace( /(?:^|\s)oldClass(?!\S)/g , '' );
// replace:
var regExp = new RegExp('(?:^|\\s)' + oldClass + '(?!\\S)', 'g');
object.className = object.className.replace( regExp , newClass );
// add
//object.className += " "+newClass;
}
changeClass(myInput.submit,"stategood_disabled"," stategood_enabled");

Sorry to find this page 7 years too late, but here is a much simpler way to solve this problem (changing hover styles arbitrarily):
HTML:
<button id=Button>Button Title</button>
CSS:
.HoverClass1:hover {color: blue !important; background-color: green !important;}
.HoverClass2:hover {color: red !important; background-color: yellow !important;}
JavaScript:
var Button=document.getElementById('Button');
/* Clear all previous hover classes */
Button.classList.remove('HoverClass1','HoverClass2');
/* Set the desired hover class */
Button.classList.add('HoverClass1');

If it fits your purpose you can add the hover functionality without using css and using the onmouseover event in javascript
Here is a code snippet
<div id="mydiv">foo</div>
<script>
document.getElementById("mydiv").onmouseover = function()
{
this.style.backgroundColor = "blue";
}
</script>

You can use mouse events to control like hover.
For example, the following code is making visible when you hover that element.
var foo = document.getElementById("foo");
foo.addEventListener('mouseover',function(){
foo.style.display="block";
})
foo.addEventListener('mouseleave',function(){
foo.style.display="none";
})

I'd recommend to replace all :hover properties to :active when you detect that device supports touch. Just call this function when you do so as touch()
function touch() {
if ('ontouchstart' in document.documentElement) {
for (var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
var sheet = document.styleSheets[sheetI];
if (sheet.cssRules) {
for (var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
var rule = sheet.cssRules[ruleI];
if (rule.selectorText) {
rule.selectorText = rule.selectorText.replace(':hover', ':active');
}
}
}
}
}
}

This is not actually adding the CSS to the cell, but gives the same effect. While providing the same result as others above, this version is a little more intuitive to me, but I'm a novice, so take it for what it's worth:
$(".hoverCell").bind('mouseover', function() {
var old_color = $(this).css("background-color");
$(this)[0].style.backgroundColor = '#ffff00';
$(".hoverCell").bind('mouseout', function () {
$(this)[0].style.backgroundColor = old_color;
});
});
This requires setting the Class for each of the cells you want to highlight to "hoverCell".

I had this need once and created a small library for, which maintains the CSS documents
https://github.com/terotests/css
With that you can state
css().bind("TD:hover", {
"background" : "00ff00"
});
It uses the techniques mentioned above and also tries to take care of the cross-browser issues. If there for some reason exists an old browser like IE9 it will limit the number of STYLE tags, because the older IE browser had this strange limit for number of STYLE tags available on the page.
Also, it limits the traffic to the tags by updating tags only periodically. There is also a limited support for creating animation classes.

Declare a global var:
var td
Then select your guiena pig <td> getting it by its id, if you want to change all of them then
window.onload = function () {
td = document.getElementsByTagName("td");
}
Make a function to be triggered and a loop to change all of your desired td's
function trigger() {
for(var x = 0; x < td.length; x++) {
td[x].className = "yournewclass";
}
}
Go to your CSS Sheet:
.yournewclass:hover { background-color: #00ff00; }
And that is it, with this you are able to to make all your <td> tags get a background-color: #00ff00; when hovered by changing its css propriety directly (switching between css classes).

For myself, I found the following option: from https://stackoverflow.com/a/70557483/18862444
const el = document.getElementById('elementId');
el.style.setProperty('--focusHeight', newFocusHeight);
el.style.setProperty('--focusWidth', newFocusWidth);
.my-class {
--focusHeight: 32px;
--focusWidth: 256px;
}
.my-class:focus {
height: var(--focusHeight);
width: var(--focusWidth);
}

You can make a CSS variable, and then change it in JS.
:root {
--variableName: (variableValue);
}
to change it in JS, I made these handy little functions:
var cssVarGet = function(name) {
return getComputedStyle(document.documentElement).getPropertyValue(name);
};
and
var cssVarSet = function(name, val) {
document.documentElement.style.setProperty(name, val);
};
You can make as many CSS variables as you want, and I haven't found any bugs in the functions;
After that, all you have to do is embed it in your CSS:
table td:hover {
background: var(--variableName);
}
And then bam, a solution that just requires some CSS and 2 JS functions!

Had some same problems, used addEventListener for events "mousenter", "mouseleave":
let DOMelement = document.querySelector('CSS selector for your HTML element');
// if you want to change e.g color:
let origColorStyle = DOMelement.style.color;
DOMelement.addEventListener("mouseenter", (event) => { event.target.style.color = "red" });
DOMelement.addEventListener("mouseleave", (event) => { event.target.style.color = origColorStyle })
Or something else for style when cursor is above the DOMelement.
DOMElement can be chosen by various ways.

I was researching about hover, to be able to implement them in the button label and make the hover effect
<button type="submit"
style=" background-color:cornflowerblue; padding:7px; border-radius:6px"
onmouseover="this.style.cssText ='background-color:#a8ff78; padding:7px; border-radius:6px;'"
onmouseout="this.style.cssText='background-color:cornflowerblue; padding:7px; border-radius:6px'"
#click="form1()">
Login
</button>

You can create a class in css
.hover:hover {
background: #ff0000;
}
and then add it dynamically
const columns = document.querySelectorAll('table td');
for (let i = 0; i < columns.length; i++) {
columns[i].classList.add('hover');
}
But your css and js files should be connected in index.html

const tds = document.querySelectorAll('td');
tds.forEach((td,index) => {
td.addEventListener("mouseover", ()=>hover(index))
td.addEventListener("mouseout", ()=>normal(index))
});
function hover(index){
tds[index].style.background="red";
}
function normal(index){
tds[index].style.background="yellow";
}
Try this code it will work fine .

If you use lightweight html ux lang, check here an example, write:
div root
.onmouseover = ev => {root.style.backgroundColor='red'}
.onmouseleave = ev => {root.style.backgroundColor='initial'}
The code above performes the css :hover metatag.

Related

Changing table cell colors in Javascript without the use of id's

I'm working on a small project where I'd like to change the background color of a table's cells while the mouse hovers over each cell. I'm able to do it with an individual cell with document.getElementById("cell1"); etc. but haven't found a way to make life easier by selecting all of the td tags and avoiding giving each cell its own id. I've tried document.getElementsByTagName but the console returns that cell.addEventListener is not a function. I must be using the selectors wrong or am not understanding the correct usage of event handling. I've found a similar question on here but it doesn't address using solely javascript which i'd like to do.
var cell = document.getElementsByTagName("td");
cell.addEventListener("mouseover", function() {
this.style.backgroundColor="red";
cell.addEventListener("mouseout", function() {
this.style.backgroundColor="";
})
});
Why not CSS? The :hover pseudo class is much easier and conserves code length and complexity, and is ultimately faster.
td:hover{ /* insert proper selector here */
background-color:red;
}
You should be iterating the set. "The Element.getElementsByTagName() method returns a live HTMLCollection of elements with the given tag name." - https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
for(var i = 0; i < cell.length; i++){
cell[i].addEventListener("mouseover", function() {
this.style.backgroundColor="red";
};
cell[i].addEventListener("mouseout", function() {
this.style.backgroundColor="";
});
}
However, a better way to do this would be a simple hover rule in css
td:hover{
background-color: red;
}
Here is a jQuery solution
$(document).ready(function() {
$("td").on("mouseover mouseout", function() {
$(this).toggleClass("red");
});
});
http://jsfiddle.net/kwagtd0d/1
You can add and remove classes with jQuery by listening for events, but it's easiest to do this with css.
td:hover
JavaScript solution
var cells = document.getElementsByTagName("td");
This returns a collection of td elements. We can now iterate through this selection.
for(var i = 0; i < cells.length; i++){
cells[i].addEventListener("mouseover", function() {
this.classList.add("red");
};
cells[i].addEventListener("mouseout", function() {
this.classList.remove("red");
});
}
http://jsfiddle.net/qknjyaaw/

Child Div styles in javascript

I have got a preview box that gets the color and then changes it when the user does. However i have a child div that needs changine. how can i select the child div through get element by id?
this is the java script i have at the moment, how do i change this so i can get the child div front to change color
document.getElementById("flip3D").style.backgroundColor=p1;
#flip3D{
width:200px;
height:200px;
margin:20px;
float:left;
}
#flip3D > .front{
... style stuff is all there just to much toput in and worry about
}
You mean something like this?
var front = document.querySelectorAll('#flip3D .front');
for(var i=0; i<front.length; i++){
front[i].style.backgroundColor = 'red';
}
or like:
var flipEl = document.getElementById("flip3D");
var frontEl = flipEl.getElementsByClassName('front');
for(var i=0; i<frontEl.length; i++){
frontEl[i].style.backgroundColor = p1;
}
Why not do it using CSS? (Your Question is pretty unclear so my hands are tied)
You could go with .childNodes() and .children() (Google will give you a lot of learning resources for these two methods. )
They will aid in selecting child elements within the DOM, of a specific element.
My first suggestion would be to use jQuery for this type of manipulation. It makes navigating the DOM and changing attributes much easier.
My second suggestion would be to control the color of both elements with a class. So your CSS might look something like this:
#flip3D{
width:200px;
height:200px;
margin:20px;
float:left;
background: /*whatever you want the initial color to be*/;
}
#flip3D > .front {
/*Initial styling*/
}
#flip3D.stateChanged{
background: /*Whatever you want the new color to be*/;
}
#flip3D.stateChanged > .front {
/*New styling*/
}
Then in your Javascript you would change the class like this:
jQuery Example (using toggleClass):
jQuery('#flip3D').toggleClass('stateChanged');
You can also do the class manipulation in vanilla javascript but it is much messier. Something like this:
var ele = document.getElementById('#flip3D');
if(ele.className == 'stateChanged')
ele.className = '';
else
ele.className = 'stateChanged';
The simpleste way to do this is by using CSS. Change the background-color to inherit, that way they will allways have the color of their parent.
.child-node {
background-color: inherit;
}

Dynamically changing cursor/setting cur files

How can I dynamically change the style of cursors on my div using JS or CSS?
Because I have multiple situations...
I've tried the code below:
div.addEventListener("mouseover", function(evt) {
if (tool == "BC"){
div.style.cursor = "url(/icons/bc.cur)";
}
if (tool == "pan"){
div.style.cursor = "url(/icons/pan.cur)";
}
}
Assuming you're using conditional comments as in html5 boilerplate you could define this style (note the different syntax for newer browser — see MDN docs for further information):
div.bc { cursor : url(/icons/bc.cur), auto; }
div.pan { cursor : url(/icons/pan.cur), auto; }
/* style for IE<9 */
.lt-ie9 div.bc { cursor : url(/icons/bc.cur); }
.lt-ie9 div.pan { cursor : url(/icons/pan.cur); }
and, assuming for simplicity that your div hasn't any class applied, just change your js code like so:
div.addEventListener("mouseover", function(evt) {
this.className = tool.toLowerCase();
}
This approach will ensure good scalability, since in case you have another cursor to list, the javascript doesn't need to be modified further, just add a new couple of css rules. Furthermore you will totally keep off css from javascript, thus your javascript has a better mantainability.

Class CSS property return

How would one return a class computed CSS property/property array?
Like, if I have a class defined in CSS:
.global {
background-color: red;
color: white;
text-shadow: 0px 1px 1px black;
}
It's applied on the go with javascript to an element. Now I want to change this elements childrens' color to parents' (.global) element background-color.
And is there a way to read CSS properties from a previously defined class in a style tag or externally included *.css?
Something like, getCSSData([span|.global|div > h1]); (where the passed variable is a CSS selector, that gets data for exactly matching element) that would return an object with each property in it's own accessible variable?
Something like:
cssdata = {
selector : '.global',
properties : {
backgroundColor : 'red',
color : 'white',
textShadow : '0px 1px 1px black'
// plus inherited, default ones (the ones specified by W3..)
}
}
And the usage for my previously explained example would be:
// just an example to include both, jQuery usage and/or native javascript
var elements = $('.global').children() || document.getElementsByClassName('.global')[0].children;
var data = $('.global').getCSSData() || document.getCSSData('.global');
return elements.css('color', data.properties.backgroundColor) || elements.style.backgroundColor = data.properties.backgroundColor;
Is there a function built in already in javascript/jquery and I've overlooked it?
If not, what should I look for to make one?
P.S. Can be DOM Level 3 too.. (HTML5'ish..)
If you want to grab the background color of the parent element and then apply that color to the font of all of it's children you could use the following code.
$(document).ready(function(){
var global = $('.global');
var bgColor = global.css('background-color');
global.children().css('color', bgColor);
};
Here's an example on jsFiddle.net
You can access the computedStyle of an element which includes all inherited style values, here is a example that outputs the computed style of a div element in the console.
<script type="text/javascript">
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", listComputedStyles, false);
}
function listComputedStyles() {
var element = document.getElementById("myDiv");
var properties = window.getComputedStyle(element, null);
for (var i = 0; i < properties.length; i++)
{
var value = window.getComputedStyle(element, null).getPropertyValue(properties[i]);
console.log(properties[i], value);
}
}
</script>
<div id="myDiv" style="background-color: blue; height: 500px;"></div>
You can find more information here: http://help.dottoro.com/ljscsoax.php
If I understand your question correctly, you'd like to find a general approach to modifying a class; and to have that modifcation affect all of the instantiations of that class. This was the subject of another detailed discussion on SO over here.
There turned out to be an extremely interesting and useful treatment of classes that works in almost all browsers, notably excepting IE8 and below.

change div/link class onclick with js - problems

Figured out how to change the class of a div/link/whatever onclick with JS. Here's a quick demo: http://nerdi.net/classchangetest.html
Now what I'm trying to figure out is how I can revert the previously clicked link to it's old class (or "deactivate") when clicking a new link.
Any ideas? Thanks!
function changeCssClass(navlink)
{
var links=document.getElementsByTagName('a');
for(var i=0, n=links.length; i<n; i++)
{
links[i].className='redText';
}
document.getElementById(navlink).className = 'blueText';
}
With this code all links will be red and lust clicked will be blue.
I hope it will be helpfull.
function changeCssClass(ele, add_class) {
// if add_class is not passed, revert
// to old className (if present)
if (typeof add_class == 'undefined') {
ele.className = typeof ele._prevClassName != 'undefined' ? ele._prevClassName : '';
} else {
ele._prevClassName = ele.className || '';
ele.className = add_class;
}
}
Try it here: http://jsfiddle.net/Zn7BL/
Use it:
// add "withClass"
changeCssClass(document.getElementById('test'), 'withClass');
// revert to original
changeCssClass(document.getElementById('test'));
It is a much better to post your code here, it makes it easier for those reading the question and for others searching later. Linked examples are unreliable and likely won't persist for long.
Copying from the link (and formatting for posting):
<style type="text/css">
.redText, .blueText { font-family: Arial; }
.redText { color : red; }
.blueText { color : blue; }
</style>
<script language="javascript" type="text/javascript">
The language attribute has been deprecated for a very long time, it should not be used. The type attribute is required, so keep that.
function changeCssClass(navlink)
The HTML class attribute is not sepecifically for CSS, it is used to group elements. A better name might be changeClassName.
{
if(document.getElementById(navlink).className=='redText')
{
document.getElementById(navlink).className = 'blueText';
}
else
{
document.getElementById(navlink).className = 'redText';
}
}
</script>
Link 1<br><br>
When called, the function associated with an inline listener will have its this keyword set to the element, so you can call the function as:
<a ... onclick="changeCssClass(this);" ...>
Then you don't have to pass the ID and you don't need getElementById in the function.
You might consider a function that "toggles" the class: adding it if it's not present, or removed if it is. You'll need to write some small functions like hasClass, addClass and removeClass, then your listener can be:
function toggleClass(el, className) {
if (hasClass(el, className) {
removeClass(el, className);
} else {
addClass(el, className);
}
}
Then give your links a default style using a style rule (i.e. apply the redText style to all links), then just add and remove the blueText class.
You might also consider putting a single function on a parent of the links to handle clicks from A elements — i.e. event delegation.

Categories