I sat down to write a demo HTML5-ish page that lets a user to perform following operations on a canvas - draw lines, draw a filled rectangle, and reset the canvas. Each operation is represented by a button, clicking on which the operation is carried out.
My initial attempt ended up as a mingled HTML and JavaScript code. So, after a bit of reading, I used the addEventListener() method to add the events to the buttons, thus eliminating the onclick code in HTML.
Now, I followed two approaches while writing the JavaScript code.
The first, simpler approach
// Instead of forcing all event handlers to know the canvasId by themselves, I chose to hardwire it in window.onload() function, inside which I also add the event handlers to their respective buttons.
// I need to pass canvasId to the event handlers, thus forcing me to write anonymous functions.
// I won't have a future reference to the event handlers unless, of course, I store them in variables, which I find clumsy.
window.onload = function()
{
var canvasId = "DrawingBoard";
var rectangleButton = document.getElementById("rectangleButton");
rectangleButton.addEventListener("click", function() { drawFilledRectangle(canvasId); }, false);
var linesButton = document.getElementById("linesButton");
linesButton.addEventListener("click", function() { drawLines(canvasId); }, false);
var resetButton = document.getElementById("resetButton");
resetButton.addEventListener("click", function() { resetCanvas(canvasId); }, false);
}
function drawFilledRectangle(canvasId)
{
resetCanvas(canvasId);
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.fillStyle = "#eee";
context.fillRect(50, 25, 150, 120);
}
function drawLines(canvasId)
{
resetCanvas(canvasId);
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
for (var x = 0.5; x < canvas.width; x += 10)
{
context.moveTo(x, 0);
context.lineTo(x, canvas.height - 1);
}
context.strokeStyle = "#eee";
context.stroke();
}
function resetCanvas(canvasId)
{
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height);
}
The following is my second approach.
// I don't need to pass canvasId to each event handler.
// This way, I don't have to create anonymous functions, meaning that I always have a reference to the function - the function name.
// The structure still makes sense; this way, I have grouped the canvas operations along with the canvas id in a single namespace.
// Whatever you need to do with canvas, you can just add a function to the object literal CanvasOperations.
window.onload = function()
{
var rectangleButton = document.getElementById("rectangleButton");
rectangleButton.addEventListener("click", CanvasOperations.drawFilledRectangle, false);
var linesButton = document.getElementById("linesButton");
linesButton.addEventListener("click", CanvasOperations.drawLines, false);
var resetButton = document.getElementById("resetButton");
resetButton.addEventListener("click", CanvasOperations.resetCanvas, false);
}
var CanvasOperations =
{
canvasId : "DrawingBoard",
resetCanvas : function()
{
var canvas = document.getElementById(CanvasOperations.canvasId);
var context = canvas.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height);
},
drawLines : function()
{
CanvasOperations.resetCanvas(CanvasOperations.canvasId);
var canvas = document.getElementById(CanvasOperations.canvasId);
var context = canvas.getContext("2d");
for (var x = 0.5; x < canvas.width; x += 10)
{
context.moveTo(x, 0);
context.lineTo(x, canvas.height - 1);
}
context.strokeStyle = "#eee";
context.stroke();
},
drawFilledRectangle : function()
{
CanvasOperations.resetCanvas(CanvasOperations.canvasId);
var canvas = document.getElementById(CanvasOperations.canvasId);
var context = canvas.getContext("2d");
context.fillStyle = "#eee";
context.fillRect(50, 25, 150, 120);
}
};
Note that I have provided my reasoning of both the approaches in their respective comments.
Which approach is better?
Are my reasons to lean towards the second one right?
What approach should I take while using attributes like id or name of HTML elements in JavaScript code?
I think hardwiring should be as less as possible. Is there anything you can point me to for learning? Or is it just intuition thing, to be decided by me? I did Google on this, but couldn't find a right solution; or I might have failed to frame a proper Google search.