Cici
Cici

Reputation: 1447

Handling "mousedown" event on different object

I am trying to change the length of two bars (div) by mouse dragging (extending one example in eloquetjavascript book chapter 14, which involves changing the length of one bar by dragging the mouse.) The intended behavior is clicking on any bar, moving the mouse when holding the left mouse key would change the length of that bar.

Here is my implementation (also available on JSfiddle)

<script>
  var lastX; // Tracks the last observed mouse X position
  var rect1 = document.getElementById("bar1");
  var rect2 = document.getElementById("bar2");
  rect1.addEventListener("mousedown", function(){watchmousedown(rect1)});
  rect2.addEventListener("mousedown", function(){watchmousedown(rect2)});                      

  function watchmousedown(rec) {
    if (event.which == 1) {
      lastX = event.pageX;
      addEventListener("mousemove",function(){moved(rec)});
      event.preventDefault(); // Prevent selection
    } else {
    removeEventListener("mousedown", watchmousedown)}
  }

  function moved(rec) {
    if (event.which != 1) {
      removeEventListener("mousemove", moved);
    } else {
      var dist = event.pageX - lastX;
      var newWidth = Math.max(10, rec.offsetWidth + dist);
      rec.style.width = newWidth + "px";
      lastX = event.pageX;
    }
  }
</script>

The problem is I can only change the length of the bar where the first mouse click event happened. I assume I didn't handle the mousedown event correctly (probably need a reset some how).

I am new to javascript, help on programming style is also appreciated.

Thanks!

Upvotes: 0

Views: 480

Answers (1)

Drew Faubion
Drew Faubion

Reputation: 461

Add rec. to addEventListener("mousemove", function () { so that the event listener is bound to the rec you clicked on instead of to the window.

function watchmousedown(rec) {
    if (event.which == 1) {
        lastX = event.pageX;
        rec.addEventListener("mousemove", function () {
            moved(rec)
        });
        event.preventDefault(); // Prevent selection
    } else {
        rec.removeEventListener("mousedown", watchmousedown)
    }
}

Edit: I there are some event handlers not being cleaned up properly. I don't know if this would be my final code, but this is closer to how I would do it:

var lastX; // Tracks the last observed mouse X position
var rect1 = document.getElementById("bar1");
var rect2 = document.getElementById("bar2");

var moveRect1 = function () {
    console.log(arguments);
    moved(rect1)
};
var moveRect2 = function() {
    console.log(arguments);
    moved(rect2);   
}
var watchRect1 = function () {
    console.log(arguments);
    watchmousedown(moveRect1)
};
var watchRect2 = function () {
    console.log(arguments);
    watchmousedown(moveRect2)
};

rect1.addEventListener("mousedown", watchRect1);
rect2.addEventListener("mousedown", watchRect2);

window.addEventListener("mouseup", function() {
   removeEventListener("mousemove", moveRect1); 
   removeEventListener("mousemove", moveRect2); 
});

function watchmousedown(moverec) {
    if (event.which == 1) {
        lastX = event.pageX;
        addEventListener("mousemove", moverec);
        event.preventDefault(); // Prevent selection
    }
}

function moved(rec) {
    if (event.which == 1) {
        var dist = event.pageX - lastX;
        var newWidth = Math.max(10, rec.offsetWidth + dist);
        rec.style.width = newWidth + "px";
        lastX = event.pageX;
    }
}

Edit: removed a line that didn't do anything

Upvotes: 1

Related Questions