In another Stack Overflow question (Creating a clickable grid in a web browser), an answerer posted this as an example: http://jsfiddle.net/6qkdP/2/.
I was attempting to do something similar while learning JavaScript, but this answer provided more questions than answers. Now, I think I understand the concept of functions that return functions. However, the JS posted on that jsfiddle link confuses me, and here's why...
On line 15, the function is created:
function clickableGrid( rows, cols, callback ){...}
It seems simple: pass in the number of rows and columns, and pass whatever function is being called back (right?). Up top, on line 2, it calls that function, and for the callback, it's passing a function that accepts a few things (el, row, col, i)
and provides output in the Console.
var grid = clickableGrid(10,10,function(el,row,col,i){...}
That all seems easy to understand (assuming, of course, I understand it correctly!). But then this bit starting on line 24 confuses me:
It creates a click event listener for the <td>
element being created. This event listener calls a new function that accepts 4 parameters...
cell.addEventListener('click',(function(el,r,c,i){
...which returns another function...
return function(){
...which is a callback of the main function, passing those same 4 parameters (?)...
callback(el,r,c,i);
}
...and then this bit is what gets passed during the click event?
})(cell,r,c,i),false);
Is that right? It all seems overly confusing to me...for instance, I don't understand why one function was created that accepts the same parameters, and changes the style of the <td>
element right then and there, without requiring all of these callbacks? I'm missing something, and hoping that the more experienced folks here can provide input on what it is that I'm not grasping.
Code, in case JSFiddle is down:
var lastClicked;
var grid = clickableGrid(10,10,function(el,row,col,i){
console.log("You clicked on element:",el);
console.log("You clicked on row:",row);
console.log("You clicked on col:",col);
console.log("You clicked on item #:",i);
el.className='clicked';
if (lastClicked) lastClicked.className='';
lastClicked = el;
});
document.body.appendChild(grid);
function clickableGrid( rows, cols, callback ){
var i=0;
var grid = document.createElement('table');
grid.className = 'grid';
for (var r=0;r<rows;++r){
var tr = grid.appendChild(document.createElement('tr'));
for (var c=0;c<cols;++c){
var cell = tr.appendChild(document.createElement('td'));
cell.innerHTML = ++i;
cell.addEventListener('click',(function(el,r,c,i){
return function(){
callback(el,r,c,i);
}
})(cell,r,c,i),false);
}
}
return grid;
}