2

Essentially, I want a user to be able to click and hold down their mouse and scroll over any number of cells in the table, as soon as they scroll over a cell it should change color. The thing is that when the user regularly clicks a cell I want the cell to change color, and I have a separate event listener that does that.

This is my table in html

<table class="c-table" onmousedown="hoverColorFill()">

and this is the js function I made to try to handle the hover on mousedown situation I described this:

function hoverColorFill(){
    elements = document.querySelectorAll(':hover');
    for(let i=0; i<elements.length; i++){
    elements[i].style.backgroundcolor = colorEl.value
       }
}

this is the code I have for when someone simply clicks I cell:

table.addEventListener('click', (event) => {
  const rows = document.querySelectorAll('tr');
  const rowsArray = Array.from(rows);
  const rowIndex = rowsArray.findIndex(row => row.contains(event.target));
  const columns = Array.from(rowsArray[rowIndex].querySelectorAll('td'));
  const columnIndex = columns.findIndex(column => column == event.target);
  document.querySelector(".c-table").tBodies[0].rows[rowIndex-1].cells[columnIndex].style.backgroundColor = colorEl.value
})

it doesn't seem that the hoverColorFill() function works, when I drag my mouse over my table the function gets called (it can print to the console) but it doesn't change the colors. My click event listener function completely properly, but it does occasionally give this error: Uncaught TypeError: Cannot read properties of undefined (reading 'style')at HTMLTableElement. but the function that is not working doesn't throw any errors.

Edit: the reason I am not using an eventListener here is because I couldn't figure out how to do it so that it pays attention to both the hover and the mouseover.

  • Please visit [help], take [tour] to see what and [ask]. Do some research, search for related topics on SO; if you get stuck, post a [mcve] of your attempt, noting input and expected output, preferably in a [Stacksnippet](https://blog.stackoverflow.com/2014/09/introducing-runnable-javascript-css-and-html-code-snippets/) – mplungjan Jan 09 '22 at 08:16

2 Answers2

1

The code for coloring a cell seems quite complex.

This snippet just adds a class to the element.

There does however need to be a bit more complexity about remembering when the mouse is down, and therefore coloring is to take place on mousemove, and to remember when the mouse is up.

The up and down events might take place outside the table so are sensed on the whole document.

Also, when moving the mouse when it is down the default in the browser is usually to add a background color (the user is thought to be doing a selection). This snippet sets this to transparent for the table so it's easier to see the coloring as it is happening.

const table = document.querySelector('table');
let mouseIsDown = false;
table.addEventListener('click', function() {
  event.target.classList.add('colorCell');
});
document.addEventListener('mousedown', function() {
  mouseIsDown = true;
  event.target.classList.add('colorCell');
})
document.addEventListener('mouseup', function() {
  mouseIsDown = false;
});
table.addEventListener('mouseover', function() {
  if (mouseIsDown) event.target.classList.add('colorCell');
});
td.colorCell {
  background-color: yellow;
}

table::selection,
tr::selection,
td::selection {
  background-color: transparent;
}
<table>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
</table>
A Haworth
  • 30,908
  • 4
  • 11
  • 14
  • the user selects a color using a selector that's on my page. Where in this code would I add a the line to change the background color for the cell to this particular color (colorEl.value)? – afunnyworld Jan 09 '22 at 22:44
  • You could use var(—color) instead of yellow in the CSS and then in the JS you can setProperty on the table element to colorEl.value. – A Haworth Jan 10 '22 at 06:57
1

colorTd() function checks if you've clicked on a td and then adds a class to it
It'll active when you click on it or drag your mouse along when you're clicking
Whether you're dragging your mouse while clicked is checked by onmousedown and onmouseup. It is stored in mouseIsDown

When you're mouse is over the table (determined by onmouseover ) and when mouseIsDown is true, colorTd() function will execute, giving tds a class

const table = document.querySelector("table");
const className = "selected";
let mouseIsDown = false;

const colorTd = (e) => (e.target.tagName = "TD" && e.target.classList.add("selected"));
table.onclick = (e) => colorTd(e);

document.onmousedown = (e) => {
  mouseIsDown = true;
  colorTd(e);
};

document.onmouseup = () => (mouseIsDown = false);
table.onmouseover = (e) => mouseIsDown && colorTd(e);
td {
  cursor: pointer;
  font-size: 22px;
}

td.selected {
  background-color: lightblue;
}

table::selection,
tr::selection,
td::selection {
  background-color: transparent;
}
<table>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
  <tr>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
</table>
Anuja Nimesh
  • 408
  • 3
  • 13
  • Thank you so much for this, it's really helpful. I just am confused about one thing, the selected tag you're adding to the td. What does it do? Wouldn't it make more sense to add the background color to the td there? The user chooses the background color using a selector on the page, colorEl.value holds this selection. Sorry if this is obvious, I am relatively new to using js for DOM manipulation. – afunnyworld Jan 09 '22 at 22:39
  • actually I got it to work how I want using your code - thank you so much, made my code much more efficient and it really works! Thank you :) – afunnyworld Jan 09 '22 at 22:56