-1

I'm trying out a dark mode in my app where there is a table with data. For some reason I have to set the table row background hover color with Javascript. Now there is only one background hover color for both dark and light mode. For example, if my background hover effect is set to red with Javascript for the light mode, then it is red for dark mode also, which looks horrible. If I put the mouseout and mouseover events inside the if statements in switchTheme function, it doesn't work.

What I want is to set the background hover color to be different according to the mode I am on. If I'm on light mode, I'll have say, red/white hover background color and when I'm on dark mode, it will automatically change to say, blue/green.

This is the snippet:

const toggleSwitch = document.querySelector('#dark-mode-button input[type="checkbox"]');

function switchTheme(e) {
    if (e.target.checked) {
        document.documentElement.setAttribute('data-theme', 'dark');
        
    }else {        
        document.documentElement.setAttribute('data-theme', 'light');
        
    }    
}

toggleSwitch.addEventListener('change', switchTheme, false);


$("body").on("mouseover", "table tr", function() {
    $(this).css("background", "red");
});

$("body").on("mouseout", "table tr", function() {
    $(this).css("background", "#fff");
});
:root {
  --primary-color: #495057;
  --bg-color-primary: #F5F5F5;
}

body{
  background-color: var(--bg-color-primary); 
}

[data-theme="dark"] {
  --primary-color: #8899A6;
  --bg-color-primary: #15202B;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
  background-color: #fff;
}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dark-mode-button">
    <input id="chck" type="checkbox">Dark Mode
    <label for="chck" class="check-trail">
      <span class="check-handler"></span>
    </label>
</div>

<table class="table">
    <thead>
      <tr>
          <th>Header 1</th>
          <th>Header 2</th>
          <th>Header 3</th>
      </tr>
    </thead>  
    <tbody>
      <tr>
        <td>Alfreds Futterkiste</td>
        <td>Maria Anders</td>
        <td>Germany</td>
      </tr>
      <tr>
        <td>Centro comercial Moctezuma</td>
        <td>Francisco Chang</td>
        <td>Mexico</td>
      </tr>
      <tr>
        <td>Island Trading</td>
        <td>Helen Bennett</td>
        <td>UK</td>
      </tr>
      <tr>
        <td>Laughing Bacchus Winecellars</td>
        <td>Yoshi Tannamuri</td>
        <td>Canada</td>
      </tr>
      <tr>
        <td>Magazzini Alimentari Riuniti</td>
        <td>Giovanni Rovelli</td>
        <td>Italy</td>
      </tr>
    </tbody>                     
</table>
Zak
  • 860
  • 16
  • 39
  • 3
    May I suggest using [css:hover](https://developer.mozilla.org/en-US/docs/Web/CSS/:hover)? Also be aware that your `mouseover` and `mouseout` selectors are not identical. – Lain Jul 21 '20 at 10:06
  • Fixed the selector. Sorry I can't use that as I want to set the hover effect through the Javascript for some reason. I have a dynamic table and there's an issue of ```rowspan```. So when I use css hover then some part gets hovered while some doesnt. So thats why I have to set the hover effect through JS – Zak Jul 21 '20 at 10:11
  • Your explanation of why you allegedly can’t use CSS, sounds bogus. All you are doing via JS, is react to the hover of full table rows, and then set the background for those. Your explanation of why that should not be possible using just `tr:hover { background: red; }`, makes little sense so far, with the code you have shown. You mention rowspan, but I don’t see that in your HTML, and I don’t see your JS code taking it into account in any way either. – CBroe Jul 21 '20 at 10:17
  • This is not the actual table I have been working on. You can't just come and say it's bogus without understanding the issue. I can't use css because I have a reason. And that's not what I'm looking for. Ever heard of "table hover zebra effect"? I have that with my dynamic data. And I have to post 500 lines of code to explain that. Rather I want to do it with JS. So if you can't have a solution for that with JS, then move on please. – Zak Jul 21 '20 at 10:21
  • 1
    There is an example with Zebra effect, which still does not require javascript: https://stackoverflow.com/questions/15464831/table-with-rowspan-hover-and-zebra-effect But you are correct: if you want to go with javascript, you are free to do so. – JavaScript Jul 21 '20 at 12:18

3 Answers3

1

The fastest/easiest way keeping your current code is to just check the data-theme attribute you set using switchTheme() and set colours accordingly.

$("body").on("mouseover", "table tr", function(){
    let tColor = (document.documentElement.getAttribute('data-theme') === 'dark') ? 'blue' : 'red';
    $(this).css("background", tColor)
});

$("body").on("mouseout", "table tr", function(){
    let tColor = (document.documentElement.getAttribute('data-theme') === 'dark') ? 'green' : 'white';
    $(this).css("background", tColor)
});

I believe it is better to just remove the background on mouseout to default back to the stylesheet defined background:

$("body").on("mouseout", "table tr", function(){
    $(this).css("background", "")
});

Yet like this the colours are not really defined in the stylesheet. Alternatively you could set the background of two hidden elements (hover/normal) in the stylesheet depending on the theme and get the computedStyle.

Lain
  • 3,657
  • 1
  • 20
  • 27
  • It works. But there's an issue. It starts off as white background. Then it changes according to the hover color. I guess I can set the background color with css. – Zak Jul 21 '20 at 12:32
  • 1
    @Zak: On the `mouseout` you should set it to blank, to default back to the stylesheet definition. Also be aware that `background` includes more than just `background-color`. – Lain Jul 21 '20 at 12:33
  • Whoa. Seriously? Can you please tell me more about that? – Zak Jul 21 '20 at 12:35
  • 1
    `background` also overwrites `background-image` for example. There is a list [here](https://developer.mozilla.org/en-US/docs/Web/CSS/background) – Lain Jul 21 '20 at 12:37
  • gotta be specific then – Zak Jul 21 '20 at 12:38
0

You can just set the :hover of the element to your variable value, for example

var(--bg-color-primary)

You do not actually need any JavaScript for light and dark themed sites. Hope that helped!

Cosmin Staicu
  • 1,809
  • 2
  • 20
  • 27
P3ntest
  • 1
  • 1
  • Sorry I can't use that as I want to set the hover effect through the Javascript for some reason. I have a dynamic table and there's an issue of rowspan. So when I use css hover then some part gets hovered while some doesnt. So thats why I have to set the hover effect through JS – Zak Jul 21 '20 at 10:13
0

Use below code

var color = ""; 
function switchTheme(e) {
if (e.target.checked) {
    document.documentElement.setAttribute('data-theme', 'dark');
    color = "red"; 
}
else { 
document.documentElement.setAttribute('data-theme', 'light');
color = "gray";
} 

$("body").on("mouseover", "table tr", function() {
    $(this).css("background", color);
});

$("body").on("mouseout", "table tr", function() {
    $(this).css("background", color);
});

when we click on checkbox we are storing the our color in one varible, when hover on table we are setting the value

Rajesh
  • 89
  • 5