Search code examples
javascriptdom-eventsonmousemove

document.onmousemove only handled by the last created object of my js class


I'm trying to create a class of movable elements, I get two this.functions in, my clique function work well for each child's of the class but my maousemauve related to a mousemove event work only for the last created object.

I think the problem came from the document.onmousemove = this.maousemauve declaration which does not include the this. statement, but I didn't find how to do else, is it even possible to do what I want to do with the class constructor or am I seeking in the wrong way?

//déclaration de classe, entre parenthéses, les paramètres "inconnus"qui me permettront de définir rapidement mes futurs objets!
class Domino {

  constructor(id, side1, side2, c) {
    this.id = id;
    this.side1 = side1;
    this.side2 = side2;
    this.lien = document.getElementById(id);
    this.c = c;


    this.clique = (event) => {
      this.c += 1;


      this.lien.style.position = 'absolute';



      if (this.c === 2) {
        this.c = 0;
        console.log(this);
        return this.c;
      }

      console.log(this.c);
      return this.c;

    }


    this.maousemauve = (event) => {
      if (this.c === 1) {
        console.log(this.c);
        this.lien.style.left = event.clientX - 50 + 'px';
        this.lien.style.top = event.clientY - 30 + 'px';
      }
    }


    this.lien.onclick = this.clique;
    this.lien.onmousemove = this.maousemauve;

  }
}

var d1 = new Domino("d1", 0, 1, 0);
var d2 = new Domino("d2", 0, 1, 0);
var d3 = new Domino("d3", 0, 1, 0);


console.log(d1);
console.log(d2);
console.log(d3);
body {
  width: 1000px;
  height: 800px;
}


/*j'utilise les propriétés flex pour aligner les mots au centre dans mes dominos!*/

#d1 {
  width: 100px;
  height: 60px;
  background-color: black;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
}

#d2 {
  width: 100px;
  height: 60px;
  background-color: black;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
}

#d3 {
  width: 100px;
  height: 60px;
  background-color: black;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
}
<body>
  <br /><br />
  <div id="d1"> d1 </div>
  <div id="d2"> d2 </div>
  <div id="d3"> d3 </div>
</body>


Solution

  • I read in your comments that you apparently found a solution by yourself... that did not work well.

    So here's some tips:

    • Use Element#addEventListener() instead of Element#onXXX properties for setting events.
    • Add a property (Domino#isMoving in my example) which will allow you to know if your element is currently moving. (Maybe Domino#c was that one in your code, but I was not sure.)
    • The click event will reverse the isMoving value. Then, it will add a mousemove event if isMoving === true, or will remove it if not. The event need to be attached to the document, or your issue: "if i'm moving my cursor to fast, the domino will not follow the cursor" will not be corrected.

    Check at that simplified example:

    class Domino {
      constructor(id) {
        this.id = id;
        this.lien = document.getElementById(id);
        
        // Allows to know if the domino is moving or not.
        this.isMoving = false;
        
        this.lien.addEventListener('click', (e) => {
          this.listenOnClick(e);
        });
      }
      
      listenOnClick(e) {
        const handleMouseMove = (e) => {
          this.listenOnMouseMove(e);
        };
      
        this.lien.style.position = 'absolute';
        
        // If not moving, it is moving...
        // Or if it's moving, it's not moving!
        this.isMoving = !this.isMoving;
        
        // If it's moving, add an event listener on the document when the mouse is moving
        if (this.isMoving) {
          // Attachs the listener on document, because the mouse is *always* on the document. So even if the mouse is outside the domino, it will move.
          document.addEventListener('mousemove', handleMouseMove);
        } // Or if it's not, remove that event.
        else {
          document.removeEventListener('mousemove', handleMouseMove);
        }
      }
      
      listenOnMouseMove(e) {
        if (this.isMoving) {
          this.lien.style.left = e.clientX - 50 + 'px';
          this.lien.style.top = e.clientY - 30 + 'px';
        }
      }
    }
    
    let d1 = new Domino('d1');
      d2 = new Domino('d2');
    body {
      width: 1000px;
      height: 800px;
    }
    
    .domino {
      width: 100px;
      height: 60px;
      background-color: black;
      color: white;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    <body>
      <div id="d1" class="domino">d1</div>
      <div id="d2" class="domino">d2</div>
    </body>