MouseOver event to change TD background and text - javascript

I need to change the td background to grey and text in another td when the user's mouse goes over the first mentioned td.
I have done this so far:
<td onMouseOver="this.style.background='#f1f1f1'" onMouseOut="this.style.background='white'">
but this only changes the background of the first td and does not change the text in the second td.
Any ideas please?

Have a look at this:
function highlightNext(element, color) {
var next = element;
do { // find next td node
next = next.nextSibling;
}
while (next && !('nodeName' in next && next.nodeName === 'TD'));
if (next) {
next.style.color = color;
}
}
function highlightBG(element, color) {
element.style.backgroundColor = color;
}
HTML:
<td onMouseOver="highlightBG(this, 'red');highlightNext(this, 'red')"
onMouseOut="highlightBG(this, 'white');highlightNext(this, 'black')" >
DEMO
Note that adding the event handler in the HTML is not considered to be good practice.
Depending on which browser you want to support (it definitely won't work in IE6), you really should consider the CSS approach which will work even if JS is turned off. Is much less code and it will be easier to add this behaviour to multiple elements:
td:hover {
background-color: red;
}
td:hover + td {
color: red;
}
DEMO

You should give that other td an id and access it from your onmouseover event handler. Maybe you should put that onmouseover code into its own function and call it from the onmouseover.

Related

Change color in a number of different divs that all share the same class

I have a site with a lot of different div. The thing they have in common is all share (besides their unique classes) a shared class. Lets just call it .changeClass.
What I am looking for is code with a button (or radio buttons) and by clicking the button, the background instance of all these divs will get the same one (which the .changeClass has). So the .changeClass will just be active when the button is toggled/clicked.
I am looking for a way to do this with pure javascript and no Jquery.
Sorry for being a noob :-)
In the solution below, clicking the <button> element will add/remove the class style .changeClass to all elements that have the class style .apply applied.
let button = document.getElementById('change');
let containers = document.getElementsByClassName('apply');
function changeButtonText() {
if(button.innerHTML === "Add")
button.innerHTML = "Remove";
else
button.innerHTML = "Add";
}
button.addEventListener('click', function() {
for(let index = 0 ; index < containers.length ; ++index)
containers[index].classList.toggle('changeClass');
changeButtonText();
});
div {
margin-top: 25px;
}
.apply {
border: 3px solid black;
}
.changeClass {
background-color: black;
color: white;
border: 3px solid red;
margin-top: 25px;
}
<button id="change">Add</button>
<div class="apply">1</div>
<div class="apply">2</div>
<div class="apply">3</div>
<div class="apply">4</div>
<div class="apply">5</div>
First lets get all divs that are on the DOM
const divs = document.getElementsByTagName("div");
You will have array of all the divs that are on the DOM. Then add your class to all of it. In order to do that, lets loop it.
divs.forEach(div => div.className += div.className + " changeClass");
Could this be what you are looking for?
In html:
<button onclick="changeColor('blue');">blue</button>
In JS
function changeColor(newColor) {
var elem = document.getElementsByClassName("changeClass");
elem.style.color = newColor;
}
The HTML color can be any color you would like it to be, just change they name from blue to any color or input a hex code.
We have multiple divs with the same class value
We have given a function to the button that we want the event to happen when it is clicked, using the onclick method. Now when we click the button, the function called myFunction will run.
HTML:
<div class="changeClass">Im Example Div</div>
<div class="changeClass">Me Too</div>
<button type="submit" onclick="myFunction()">Click To Change Div BgColors !
</button>
We must define myFunction as Javascript and change the background color.
We have defined a function called myFunction.
With the getElementsByClassName selector in our function, we got all the data with the class value changeClass in object format.
To add a background (or any css property) to all of these objects; We put the object in a for loop and now we split our elements.
We can now define a background color for our elements with the style.backgroundColor parameter.
JavaScript:
function myFunction(){
var divs = document.getElementsByClassName('changeClass');
for(var i=0; i< divs.length; i++){
divs[i].style.backgroundColor = 'red';
}
}
For more detailed information, you can refer to the resources: https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp
Don't be sorry for being new at something and wanting to learn more!
So what you are saying is that the divs you want to change all have a common class of "changeClass". If this is the case then you want a function is passed an argument value of the color you want to be changed. Since all of your divs are static and you probably don't plan on changing, declare a variable outside of this function that has the following code
const divs = document.getElementsByClassName("changeClass")
Then, inside of the function, loop through all of the divs collected inside the variable "divs", or whatever you want to call it. Since "getElementsByClassName" returns a collection, it does not have the built in "foreach" and "map" methods. So you have to use a for loop preferably the following.
const divs = document.getElementsByClassName("changeClass");
function changeColor(color) {
for (let element of divs) {
element.style.backgroundColor = color;
}
}
I may have interpreted this wrong but I hope it helps
You may find using a CSS variable helpful.
For example:
function bg(color) {
document.body.style.setProperty('--bg', color);
}
body {
--bg: cyan;
}
.container {
display: flex;
gap: 1vw;
}
.container div {
width: 100px;
height: 100px;
background-color: black;
}
.container div.changeClass {
background-color: var(--bg);
}
<body>
<button onclick="bg( 'red');">Red</button>
<button onclick="bg( 'green');">Green</button>
<button onclick="bg( 'blue');">Blue</button>
<button onclick="bg( 'black');">Black</button>
<div class="container">
<div class="changeClass"></div>
<div class="changeClass"></div>
<div class="changeClass"></div>
<div></div>
<div class="changeClass"></div>
</div>
</body>
Then when one of the radio buttons is clicked it sets the variable --bg.
Here's a simple snippet:
First of all - thank you for all your replies. And yes I should have included code. I tried so many things that i just gave up at som point - got confused what was right code and what was just rubbish. So I appreciate so much that you all took time to answer me. This was my first post so now I know for the future. The answers I got all was possible ways to solve my problem - so thank you all. I will do better next time. You are awesome...
BTW - All solutions seems to work - but can only checkmark one of them as you know.
You can add or remove a class to change the colours of different div:
document.queryselector('.className').classList.add('classNamethatyouwanttoadd');
document.queryselector('.className').classList.remove('classNamethatyouwanttoadd');

How to change the background of a row in an HTML table using toggle classlist

I want to change the background color of a row if the value in the table cell goes above a certain value.
I have tried implementing the toggle class as well as adding and removing classes with no luck. When I manually implemented the background color it worked.
I know I am trying to toggle a class vs a style, but is there any way I can toggle a style to change the background color?
var mq2 = 5;
if (mq2 >= 5) {
document.getElementById("row1").classlist.toggle("change2");
} else {
document.getElementById("row1").classlist.toggle("change1");
}
.change1 {
background-color: #FF6347;
}
.change2 {
background-color: #90EE90;
}
<tr id="row1">
Your code should work. You could improve it by creating a variable referencing the element
const row = document.getElementById("row1");
if(someCondition) {
row.classList.toggle("change2");
} else {
row.classList.toggle("change1");
}
The approach you are taking is fine, just make sure you capitalize classList correctly.
document.getElementById('row1').classList.toggle('change1');

mouseover event propagation issue - Manually propagate

I am implementing an User Interface for a project I'm working on and can be found here : Toobrok
Each time the mouse of the user enters a div, a class is added to this div to highlight it, I use the stopPropagation() method to restrict the highlighting to the div whose z-index is higher (the top div in the z axis).
However, sometimes, my user needs to select an element hidden by another one, when the dimensions of the 2 elements are different, and if the bottom div is larger, he can find some points of the bottom div not hidden by the top one, but when the dimensions are the same, I would like the user to be able to press a key to change the depth (on the z-axis) of his selection.
The relevant code is given below (in CoffeeScript), but a javascript solution would also help me:
Ui.bind = (elements, index) ->
ids = Ui.getIdSelector(elements)
$(ids).attr("centroid", index)
$(ids).mouseover (event) ->
event.stopPropagation()
Ui.highlight $(ids)
$(ids).mouseout (event) ->
event.stopPropagation()
Ui.resetHighlight $(ids)
I hope the question is clear and looking forward to your answer.
This is an example of HTML to consider :
<!DOCTYPE html>
<html>
<head>
<title> Sample page </title>
</head>
<body>
<div id="container">
<div id="child1">Some text...</div>
</div>
</body
</html>
And the related css :
#container {
height: 200px;
width: 500px;
}
#child1 {
height: 90%;
width: 90%;
}
When the mouse enters the child1 element, this element is highlighted, I want the container element to highlight when the user press a specific key.
I could use the JQuery parent() function to select that element on this example, but I am not sure it is a good solution, sometimes, the parent can have a size of 0px and and then a mouseover on this element would not be consistent. I want to select the element normally selected by Javascript if I do not use the stopPropagation() event.
I actually just found something that might help :
How to undo event.stopPropagation in jQuery?
But I cannot use that in my case... Because my condition is another user action, and I cannot synchronously wait for an user to do something.
I started writing code but then decided to leave implementation to you. Here is the text explanation:
At some point of time (probably when user press button to cycle through all hovered elements) you have to find all candidates for highlighting. There is no other way to do it rather than manually loop through all your elements and check if mouse position is inside their bound rect. You can get mouse coordinates from argument in mouseover callback. Save all these hovered elements in some array.
Next, you have to manually choose which element to highlight. Just highlight the first element in saved array and move the element to the end of array. You also may want to increase this element z-index and add callback for mouseout to this element.
Hope it helps, feel free to ask if you need more details.
You could use the CSS property pointer-events to make the child insensitive. Then events will be targeted to the element displayed below. For simple highlighting you should use pure CSS, however, jQuery can be helpful not to highlight the parent element as well while child is hovered without Ctrl.
Some example (also uploaded to JSFiddle, click into the output pane to make it responsive for keyboard events):
<div id="container1" class="container">
<div id="child1" class="child">Some text...</div>
</div>
div { border:1px dashed red; } /* for demo */
.container
{ height: 200px;
width: 500px;
}
.child
{ height: 90%;
width: 90%;
}
.insensitive
{ pointer-events:none;
}
.container:hover:not(.no-hilight),
.child:hover
{ background-color:yellow;
}
/* other color for demo */
.child:hover{ background-color:green; }
// make events passthrough child when <Ctrl> is held down
$(document).on('keydown keyup', function(ev) {
if (ev.key === 'Control') // for performance
$('.child')[ev.ctrlKey?'addClass':'removeClass']('insensitive');
});
// don't hilight container when child is hovered
$('.child').on('mouseover', function(ev)
{
$('.container').addClass('no-hilight');
});
// never suppress hilight when container is hovered directly
$('.container').on('mouseover', function(ev)
{ if(ev.target === ev.currentTarget)
$('.container').removeClass('no-hilight');
});
// just test which element a click is targeted to
$(document).on('click', function(ev)
{ console.log('click:', ev.target);
});
var preId = 0;
function makeBlack(id)
{
if(id)
{
$('#'+id).css('border-color','black');
}
}
function makered(id)
{
$('#'+id).css('border-color','red');
}
$(document).ready(function(){
$('div').mouseout(function() {
var currentid = this.id;
makeBlack(currentid);
preId = currentid;
});
$('div').mouseleave(function() {
var currentid = this.id;
makeBlack(currentid);
preId = currentid;
});
$('div').mouseover(function() {
var currentid = this.id;
makeBlack(currentid);
makered(preId);
preId = currentid;
});
$('div').mouseenter(function() {
var currentid = this.id;
makered(currentid);
preId = currentid;
});
});
Have you tried something like this for the CSS?
#container.hover{
height: 200px;
width: 500px;
//add a background-color to that element since its a div element
//background-color: (colour)
}
i should hope that the div element would automatically highlight the container div with whichever color you have selected

Change colour of td in dynamic table generated in php

I'm creating a PHP script that will dynamically generate tr and td elements for a table. When the user clicks in a specific cell in the first column, an AJAX function executes to display additional content. This is working as it should, however, I'm having trouble with what should be simple styling. When the user clicks on a given cell, I want that row to change colour (works) until they click on another cell (doesn't work).
Since my PHP file is rather large, I'm only posting the relevant parts.
<?php
$myFiles = showMyAttrs();
foreach($myFiles as $myFile) {
echo("<tr class = 'gradeC' onClick = 'changeColour(this)' onchange = 'restoreColour(this)' >");
echo("<td onClick = 'sendCell(this)' ><img src = $msEx /></td>");
echo("<td>$myFile</td>");
echo("</tr>");
}
I've also tried using onblur instead of onchange but that gave the same result.
The Javascript functions:
function changeColour(z) {
z.style.backgroundColor = "#FFFFFF";
}
function restoreColour(y) {
y.style.backgroundColor = "#00FF00";
}
Before I also tried:
function changeColour(z) {
document.getElementsByTagName("tr").style.backgroundColor = "#00FF00";
z.style.backgroundColor = "#FFFFFF";
<!-- document.getElementsByTagName("td").style.backgroundColor = "#00FF00"; -->
}
function changeColour(z) {
z.style.backgroundColor = "#FFFFFF";
document.getElementsByTagName("tr").style.backgroundColor = "#00FF00";
}
$('tr').click(function() {
$('tr').css('backgroundColor', '#0F0');
$(this).css('backgroundColor', '#FFF');
});
With each of them (except the last), the colour does change to white, however, when the user clicks on any other row, the previous row doesn't return to green. I don't mind if this works with Javascript or JQuery, as long as it is compatible across browsers. Even a fancy CSS trick I'm fine with using.
You're on the right track. I think adding/removing a class would be a good way to go. You could try this:
jQuery
$('tr').on('click', function() {
$('tr').children('td').removeClass('active');
$(this).children('td').addClass('active');
});
CSS
.active { background-color: yellow; }
See jsFiddle
Try using a css class to assign the background color:
$('.gradeC td').on('click',function(e){
if(!$(this).closest('tr').hasClass('green')){
$(this).closest('tr').addClass('green');
}else{
$(this).closest('tr').removeClass('green');
}
});
See demo here

how to make javascript function call two divs

i am trying to make a colour change when a button is clicked and i managed to do this however i want to change the colour of not just the main content container but more containers how do i do this?
function changeblackandwhite(objDivID) {
if(document.getElementById(objDivID).style.color=='black'){
document.getElementById(objDivID).style.color='white';
document.getElementById(objDivID).style.backgroundColor='black';
}
else if(document.getElementById(objDivID).style.color=='white'){
document.getElementById(objDivID).style.color='black';
document.getElementById(objDivID).style.backgroundColor = 'white';
}
else{
document.getElementById(objDivID).style.color='black';
document.getElementById(objDivID).style.backgroundColor='white';
}
}
<img src="images/colour.jpg" title="Change Text/Backgroud Colors">
There are dozens of ways you can accomplish this.
You could change the argument of your function to be an array of strings. You could also reduce the complexity of your function as well
<script type="text/javascript">
changeblackandwhite = function() {
for( var idx=0; idx < arguments.length; idx++) {
var tgtDiv= document.getElementById(arguments[i]);
if(tgtDiv.style.color=='black'){
tgtDiv.style.color='white';
tgtDiv.style.backgroundColor='black';
}
else{
tgtDiv.style.color='black';
tgtDiv.style.backgroundColor='white';
}
}
};
</script>
<img src="images/colour.jpg" title="Change Text/Backgroud Colors">
As another reader questioned - you can do this with jQuery in a single line.
With jQuery, you can declare the elements in question to have a class attribute.
Using jQuery, you can then do something like:
$('div.someClass').css({'color': 'black', 'background-color': 'white'});
The argument to jQuery can be a class based selector, an id based selector, or any other selector you choose.
If you are open to jquery and you assign 1 class in common with these two divs you can do the following:
This should get you started (see this jsfiddle): I changed the fiddle to include a neater solution where clicking on the button adds and removes classes on the containers which allows you to set multiple attributes including the text color in one quick call.
<div class='container'>
</div>
<div class='container'>
</div>
<button id="changeColor" type="button">Change Color </button>
<script type="text/javascript">
$(document).ready( function() {
$('#changeColor').click( function() {
if ($('.container').hasClass("blackContainer")){
$('.container').addClass("whiteContainer");
$('.container').removeClass("blackContainer");
} else {
$('.container').removeClass("whiteContainer");
$('.container').addClass("blackContainer");
}
});
});
</script>
//CSS
.blackContainer {
background-color: black;
color: white;
}
.whiteContainer {
background-color: white;
color: black;
}
I made a jsfiddle for you to play around with jsfiddle
I also did the javascript/jQuery in a similar way as the OP since it usually helps them understand.
As stated above, there are several different ways to do this, I've done but one.
The document.ready function sets up an event listener for the object to be clicked, most of the time this is how you'll see events coded. So when the link is clicked, it calls the function with the string name of the object the listener is for.
$(document).ready(function() {
$("#changeit").click(function(){
changeblackandwhite("Maincontainer");
})
});
After the event listener is assigned, it will call the function below when the link is clicked on.
// Here's your function, put the current color in a var, check if it's black
// if black, change colors, else make it black.
function changeblackandwhite(objDivID) {
var curColor = $("#" + objDivID).css("color");
if( curColor == 'rgb(0, 0, 0)'){
$("#"+objDivID).css({'color':'white','background-color':'black'});
} else {
$("#"+objDivID).css({'color':'black','background-color':'ghostwhite'});
}
}

Categories

Resources