1

I am trying to add my own object parameter to a canvas element as in jquery (like it adds element_id.draggable, element_id.resizable etc to the dom elements). My piece of code looks like this:

window.addEventListener("DOMContentLoaded",handler,false);
function handler()
{
     HTMLCanvasElement.prototype.animateLine=function(x1,x2,y1,y2,params) {
     if(params)
             init(this,x1,x2,y1,y2,params.lineColour,params.lineWidth,params.divisions,params.totalTime,params.callback);
     else
             init(this,x1,x2,y1,y2);
     };
}

So that when a user declares a canvas tag, he can directly call canvas_id.animateLine() to execute the above function.

But the problem occurring is that when the user call animateLine() in body onload or window onload, then it does not work (says animateLine is undefined).

I wanted to know that is this the right way to implement this? Also how can I remove the error from the above piece of code since I too have to call it on body/window onload?

EDIT: Updated code to call function on DOM ready, still it will not work if the user calls animateLine on DOM Ready. Any solution to this?

gopi1410
  • 6,567
  • 9
  • 41
  • 75
  • 1
    try adding animateLine when the dom is loaded, not the window. The DOM is loaded when all the ELEMENTS are loaded. window.onload fires after for all the resources have been downloaded. downloaded. Here's a link: http://stackoverflow.com/questions/1206937/javascript-domready#answer-1207005 – d4rkpr1nc3 May 17 '12 at 11:31
  • @d4rkpr1nc3: ok, it works but what if the user calls it on DOM ready?? then it will not work. – gopi1410 May 17 '12 at 11:56

2 Answers2

1

You seem to have 2 problems: You don't really add your init function to window.onload, you'd need to remove the () after onload. Also, it would could be that it is just overwritten by an other assignment. Use proper event listeners instead.

Second, your function is only executed once. It waits for onload, then looks around for all canvas elements it can find (at that time) and adds a (different) function to each of them.

If you really would want to add a function to every canvas element ever existing (you could dynamically create them), you would need to add your methods to HTMLCanvasElement.prototype. Yet, there is a good article about What’s wrong with extending the DOM. Read it and use another solution, e.g. the proposed object wrappers. If you use jQuery or some lib like that, you could write animateLine as a plugin for that.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • oops! I didn't come to my mind that this wont be applicable to dynamically created canvases!! thanks for reminding. – gopi1410 May 17 '12 at 12:24
0

The proper way to assign a function to an event is like this:

window.onload = function() {...};

Also it's not good to attach stuff (functions, objects, arrays, whatever) directly to DOM elements. better create an "interface" that operates on the element:

function ACanvas(id){

    //internal reference
    var canvas = document.getElementById('id');

    //the public interface
    return {
        draw : function(){
            //drawing logic that operates on "canvas"
        },
        erase : function(){
            //erase logic that operates on "canvas"
        }
    }
}

var myCanvas = ACanvas('mycanvasid'); //wrap the element
myCanvas.draw();                      //operate
myCanvas.erase();                     //operate
Joseph
  • 117,725
  • 30
  • 181
  • 234
  • yeah, I am using the same syntax `window.onload = function() {...};` & if its not good to attach stuff to DOM elements how do I assign it (as jquery does)?? – gopi1410 May 17 '12 at 12:17
  • @gopi1410 you create a wrapper object which has an internal reference to the element and an external interface that has functions that operate on it. – Joseph May 17 '12 at 12:20
  • can you provide an example or a link to do this?? I cant clearly understand what do u mean by a wrapper object. – gopi1410 May 17 '12 at 12:22