Dusan
Dusan

Reputation: 3488

Setting the mouseup event inside a class

I have a single element on my page and i need to detect mosuedown and mouseup events. It works fine, but i decided to move all my javascript inside a class. this is what i came up with so far:

class MyRectangle {
  constructor(elementId) {
    this.frame = $("#" + elementId);
    this.setListener();
  }

  setListener() {
    this.frame.on("mousedown", function(evt) {
      evt.preventDefault();
      console.log("MOUSE DOWN" + " " + evt.pageX + ", " + evt.pageY);
      $(document).bind("mouseup", this.docMouseUp);
    });
  }

  docMouseUp(evt) {
    console.log("MOUSE UP" + " " + evt.pageX + ", " + evt.pageY);
    $(document).unbind("mouseup", this.docMouseUp);
  }

}

var myRect = new MyRectangle("rectangle");
#rectangle {
  width: 100px;
  height: 100px;
  background-color: #dfca45;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id="rectangle">
</div>

This way, the mouseup event never triggers.

The JSFiddle: https://jsfiddle.net/5hd7672v/

Upvotes: 0

Views: 240

Answers (1)

Titus
Titus

Reputation: 22484

The problem is that inside the docMouseUp and the callback for the mousedown event functions, this no longer refers to the MyRectangle instance. That is because these functions are invoked by jQuery and the context (the this variable) is set to the element that generated the event.

To fix that, you can bind the MyRectangle instance like this:

let self = this;
this.frame.on("mousedown", function(evt) { 
        evt.preventDefault();
        console.log("MOUSE DOWN" + " " + evt.pageX + ", " + evt.pageY);
        $(document).bind("mouseup", self.docMouseUp.bind(self));
});

EDIT

I've missed the $(document).bind("mouseup", self.docMouseUp); call. In order to make that work, you'll need to change the reference to docMouseUp so it will point to the same function that was set as a callback.

class MyRectangle {
    constructor(elementId) {
        this.frame = $("#" + elementId);
        this.setListener();
    }

    setListener() {
        let self = this;
        this.docMouseUp = this.docMouseUp.bind(this);
        
        this.frame.on("mousedown", function(evt) { 
            evt.preventDefault();
            console.log("MOUSE DOWN" + " " + evt.pageX + ", " + evt.pageY);
            $(document).bind("mouseup", self.docMouseUp);
        });
    }

    docMouseUp(evt) {
        console.log("MOUSE UP" + " " + evt.pageX + ", " + evt.pageY);
        $(document).unbind("mouseup", this.docMouseUp);     
    }

}

var myRect = new MyRectangle("rectangle");
#rectangle {
  width: 100px;
  height: 100px;
  background-color: #dfca45;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rectangle">
</div>

Upvotes: 3

Related Questions