Javascript drag & drop - function query

Dear all

I came across the following very simple code for dragging a square around using javascript. It is drawn on the html5 canvas. Despite being very simple it has certainly exposed some gaps in my pretty flakey javascript knowledge. I am generally ok with the idea of drag and drop (i.e. start drag on mouse click, stop drag on mouse release) but my questions are as follows:

(1) I cannot see where the variable e is defined, yet it is used all the time.

(2) In the init funciton at the bottom, an onmousedown listener seems to be attached to the canvas. However it equals the function myDown, but myDown doesn’t have parentheses after it. So the myDown function is not actually going to be exectuted. So what is it doing instead?

Thanks in advance. I have tried to research this myself but haven’t had any success yet.

Matt

<!doctype html> 
<html> 
<head> 
<meta charset="UTF-8" /> 
<title>Canvas Drag and Drop Test</title> 
</head> 
<body> 
<section> 

<div> 
<canvas id="canvas" width="400" height="300"> 
This text is displayed if your browser does not support HTML5 Canvas. 
</canvas> 
</div> 

<script type="text/javascript"> 

var canvas; 
var ctx; 
var x = 75; 
var y = 50; 
var dx = 5; 
var dy = 3; 
var WIDTH = 400; 
var HEIGHT = 300; 
var dragok = false; 

function rect(x,y,w,h) { 
 ctx.beginPath(); 
 ctx.rect(x,y,w,h); 
 ctx.closePath(); 
 ctx.fill(); 
} 

function clear() { 
 ctx.clearRect(0, 0, WIDTH, HEIGHT); 
} 

function init() { 
 canvas = document.getElementById("canvas"); 
 ctx = canvas.getContext("2d"); 
 return setInterval(draw, 10); 
} 

function draw() { 
 clear(); 
 ctx.fillStyle = "#FAF7F8"; 
 rect(0,0,WIDTH,HEIGHT); 
 ctx.fillStyle = "#444444"; 
 rect(x - 15, y - 15, 30, 30); 
} 

function myMove(e){ 
 if (dragok){ 
  x = e.pageX - canvas.offsetLeft; 
  y = e.pageY - canvas.offsetTop; 
 } 
} 

function myDown(e){ 
 if (e.pageX < x + 15 + canvas.offsetLeft && e.pageX > x - 15 + 
 canvas.offsetLeft && e.pageY < y + 15 + canvas.offsetTop && 
 e.pageY > y -15 + canvas.offsetTop){ 
  x = e.pageX - canvas.offsetLeft; 
  y = e.pageY - canvas.offsetTop; 
  dragok = true; 
  canvas.onmousemove = myMove; 
 } 
} 

function myUp(){ 
 dragok = false; 
 canvas.onmousemove = null; 
} 

init(); 
canvas.onmousedown = myDown; 
canvas.onmouseup = myUp; 

</script> 

</section> 
</body> 
</html> 

When an event is triggered, information about that event is automatically passed to the function.
The above script uses e, but you can give it any name you like. It’s common to see evt used, for example.

See https://developer.mozilla.org/En/DOM/Event for details

Doe to some compatibility issues with earlier Internet Explorer, you may find some events checking that the event information really was passed, and if not fetching the info from window.event instead.


function eventHandler (evt) {
    evt = evt || window.event;
    ...
}

When assigning a function to an event, you can either directly assign a function to that event:


canvas.onmousedown = function (evt) {
    // do stuff
};

Or you can define the function somewhere else, and use a reference to that function instead.


function myDown (evt) {
    // do stuff
}
canvas.onmousedown = myDown; 

If you were to put parenthesis after mydown, that would invoke the function, resulting in the return value from the function being assigned to the event. Normally you don’t want to that to occur, unless it’s a function that is returned from the function.


function prepareMyDown () {
    // preperation stuff here
    return function (evt) {
        // do stuff
    };
}
canvas.onmousedown = prepareMyDown(); 

Dear pmw57

Hi, thanks for your reply. It is very clear, and the examples also help.

I think I went wrong as follows… I was expecting to see parentheses after the function name because I was expecting to see the function executed outright. However, it seems really we are just copying the myDown function to the canvas object. In other words, it is now a method of the canvas. In fact, I tried:

alert(canvas.onmousedown)

… which gives a pop-up containing all of the myDown code.

Am I right about this?

Thanks again

Matt

Just about. Instead of being a copy of the function, we’re instead assigning a reference to the function. It’s a minor difference of understanding, but can become important if the function is changed later on.

OK, thanks Paul. And I shall note also then that it is a reference, not a copy.

Thanks, and best wishes

Matt