View Full Version : OOP: adding Event to an Javascript object

Ben Stuijts
11-12-2012, 03:26 PM
I want to add an eventlisterer 'click' to an object, which is represented to the user as image. This wouldn't work, but shows what i want to achieve:

function object {
this.picture = null;
this.src = 'images/defualt.png';
this.id = 1;

object.prototype.setImage = function(src) {
this.picture = new Image();
this.picture.src = src;
this.picture.addEvenListener('click' , clickme, false);

clickme = function() {
alert('hurray, i'm clicked...');

11-12-2012, 04:00 PM
It would work ... but the image must be attached to the DOM otherwise it will (of course) not be visible and not be clickable.

object.prototype.clickme = function() {

object.prototype.setImage = function(src) {
this.picture = new Image();
this.picture.src = src;
this.picture.addEventListener('click' , this.clickme, false);

Ben Stuijts
11-12-2012, 07:06 PM
There is only one but... I'm drawing the picture of the object on my canvas. I should have told this:

object.prototype.draw = function(xpos, ypos) {
ctx.drawImage(this.picture,sx, sy, swidth, sheight,xpos,ypos, width, height);

NB: the vars sx, sy, swidth, sheight, width and height are optional; I would like to use them , so i can define my picture from a tilesheet.

11-12-2012, 09:21 PM
Then (of course) you need to attach the event listener to the canvas and not to the image ... because the image does not exist in the page DOM

Ben Stuijts
11-12-2012, 10:00 PM

This is a working solution, but not that great, because it wil take some calc power... I've add an eventlistener to the canvas(click). When clicking the canvas, a function will check all objects, to see you've clicked them. Not nice, but a start...

// declaring multiple objects:
var obj = new Array;
obj[0] = new object();
obj[1] = new object();

// adding to the objectclass:


canvas.addEventListener("click", select, false);

function select(e) {
var mouseX = e.offsetX || e.layerX;
var mouseY = e.offsetY || e.layerY;
//alert('canvas was clicked / mouseco÷rdinates are: ' + mouseX + ' , ' + mouseY);
var objects = obj.length;
for(var i = 0; i < objects; i++) {

var X = obj[i].xpos;
var W = X + obj[i].width;
var Y = obj[i].ypos;
var H = Y + obj[i].width;

if ( mouseX >= X && mouseX <= W && mouseY >= Y && mouseY <= H)
//alert('object found');

function object_click(id) {
alert('object with id = ' + id + 'clicked and found.');

Hopefully you will know a much better solution, because this is nice with a couple of objects, but not nice with thousands of them of course..

Sorry still learning! ;-)

rnd me
11-13-2012, 12:23 PM
you can put clear divs over the canvas to catch clicks on a known rectangular area without searching at "click-time".

you can even export the canvas to the background-image of a <table>, use css to style tr/td to size, bind onclicks to TDs, and use the onclick's e.target.cellIndex/e.target.parentNode.rowIndex to get boxy "coords".

if you want the most flexibility, build a mini mvc to avoid math at run-time.
you can use something like (posX / 30) to slice the canvas into 30px wide boxes.
once you know the box number, you can check the relationship from a simple array.
that array can hold links to whatever objects you want, I use strings in this theoretical example:

// id a click with one of these 5 model groups:
var groups=[

//a 3X3 grid of the view of groups:
var objs=[
[ 1,2,1 ],
[ 1,5,1 ],
[ 4,3,3 ]

// control click dispatches to a 90px X 90px 9panel box:

var clickedGroup= groups[
Math.floor( y / 30 )
Math.floor( x / 30 )

alert( clickedGroup ); //should be "bravo" or "delta" or one of those.

no loops, no conditionals, no long-hand pixel coords or brittle repetition.
this pattern de-couples the specific image from the physical layout and from the behavior, allowing placeholders and easy scaling.