Search code examples
javascriptfrontendclickmouseeventaddeventlistener

Is there a way to have an add event listener first execute a mousedown, then mouseover, and finally mouseup?


So right now I have a 20 by 20 grid and I want the user to be able to click and select multiple cells in the grid. There is a method I was able to find online but the problem is that mouseover takes over and highlights the cells right when the mouse is over the cells and this is not what I want. I want the user click on a cells then basically drag their mouse and highlight the cells that they want then execute mouseup once they let go.

These are my files.

let graph = document.getElementById("container");
graph.style.display = "flex";


function createGraph() {

  let j = 0;
  for (let i = 0; i < 20; i++) {
    let row = document.createElement("div");
    row.id = "row" + i;


    row.style.height = "50px";
    row.style.width = "50px";

    graph.appendChild(row);

    let currentRow = document.getElementById("row" + i);
    j++;

    for (let j = 0; j < 20; j++) {
      let cell = document.createElement("div");
      cell.classList.add("cells");
      ///id's are used later in the project
      cell.id = "index" + j + i;
      cell.style.border = "1px solid black";
      cell.style.height = "50px";
      cell.style.width = "50px";
      currentRow.appendChild(cell);


    }
  }
}

createGraph();

function main() {

  document.querySelectorAll(".cells").forEach(item => {

    ["mousedown", "mouseover", "mouseup"].forEach(function(e) {
      item.addEventListener(e, function() {
        item.style.backgroundColor = "red";
      })
    })

  })
}

main();
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Document</title>
</head>

<body>
  <div id="container"></div>
</body>

</html>

So in the main function I added an even listener to all the cells and I am trying to change their color to red. The problem is that the mouseover event takes over the mousedown which is what I want to happen first. How can I make it so the user is able to first click down on a cell then drag their mouse and keep highlighting cells and once they let go of the mouse the highlighting stops. Is there away to first execute the mousedown, then mouseover and finally the mouseup?


Solution

  • I refactored your code a little. Here is a simple example how you can use toggle state:

    let graph = document.getElementById('container');
    
    
    function createGraph() {
    
      for (let i = 0; i < 20; i++) {
        let row = document.createElement('div');
        row.id = 'row' + i;
        row.className = 'rows';
    
        for (let j = 0; j < 20; j++) {
          let cell = document.createElement('div');
          cell.className = 'cells';
          cell.id = 'index' + j + i;
          row.appendChild(cell);
        }
        
        graph.appendChild(row);
      }
    }
    
    createGraph();
    
    function main() {
    
      let canSelect = false;
    
      document.addEventListener('mousedown', () => canSelect = true);
      document.addEventListener('mouseup', () => canSelect = false);
    
      document.querySelectorAll('.cells').forEach(item => {
    
        ['mousedown', 'mouseover'].forEach(function(e) {
          item.addEventListener(e, () => {
            if (!canSelect && e !== 'mousedown') return;
            
            item.style.backgroundColor = 'red';
          })
        })
      })
    }
    
    main();
    #container {
      display: flex;
    }
    
    .rows, .cells {
      width: 50px;
      height: 50px;
    }
    
    .cells {
      border: 1px solid black;
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <title>Document</title>
    </head>
    
    <body>
      <div id="container"></div>
    </body>
    
    </html>