Event Binding On Dynamically Created Elements And Passing Parameters
Solution 1:
The point of event delegation is that you don't need to bind an event to every single element (or to the same element multiple times), just once to the common parent, like so:
functioncreateLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a class="linklink" href="#">Link_' + i + '</a>';
}
$container.html(links).on( "click", ".linklink", function(){
console.log( "fn action"+$(this).index());
});
}
createLinks();
To avoid using eval
, you could have an array of functions and call them by index:
arrayOfFunctions[ $(this).index() ]();
Solution 2:
If each action function actually has to be a different function (rather than one function that acts different based on the index passed to it), then I'd do it this way by putting an attribute on the link and fetching it upon click which you can see it work here: http://jsfiddle.net/jfriend00/gFmvG/.
functionaction0(){ console.log("fn action0"); }
functionaction1(){ console.log("fn action1"); }
functionaction2(){ console.log("fn action2"); }
functionaction3(){ console.log("fn action3"); }
var actions = [action0, action1, action2, action3];
functioncreateLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a id="link_' + i + '" href="#" data-num="' + i + '">Link_' + i + '</a>';
$container.on("click", '"#link_' + i + '"', function() {
actions[$(this).data("num")]();
});
}
$container.html(links);
}
createLinks();
If you don't have to have separate functions for each action, I'd do it like this which you can see here: http://jsfiddle.net/jfriend00/Z8Rq6/.
functiondoAction(index) {
console.log("fn action" + index);
}
functioncreateLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a id="link_' + i + '" href="#" data-num="' + i + '">Link_' + i + '</a>';
$container.on("click", '"#link_' + i + '"', function() {
doAction($(this).data("num"));
});
}
$container.html(links);
}
createLinks();
This could also be done with an executing closure which locks in the index value, but I find that syntax somewhat less readable (it takes too many brain cycles to read the code and know what it's doing) so I prefer this way with the attribute.
Solution 3:
Put your functions in an object
var myFuncs = {
action0:function(){ console.log("fn action0"); },
action1:function(){ console.log("fn action1"); },
action2:function(){ console.log("fn action2"); },
action3:function(){ console.log("fn action3"); }
};
var funcNumber = "3";
for (var i=0; i < 4; i++)
{
links += '<a id="link_' + i + '" href="#">Link_' + i + '</a>';
(function(myI)
{
$container.on("click", '"#link_' + i + '"', function()
{
myfuncs["action"+funcNumber](mI);
});
})(i);
}
course if they are being made on the global scope you could also do
for (var i=0; i < 4; i++)
{
links += '<a id="link_' + i + '" href="#">Link_' + i + '</a>';
(function(myI)
{
$container.on("click", '"#link_' + i + '"', function()
{
window["action"+funcNumber](mI);
});
})(i);
}
Solution 4:
It looks like your original problem was that you wanted to call a function whose name would be determined by the parameter passed in. Are these functions all global in scope? If so, I would just do this:
functionhelpCallback(index) {
returnfunction() {
window['action' + index]();
}
}
This has the added advantage that, if you ever wanted to pass arguments to actionX, you do so by passing these arguments after index with the following modification
functionhelpCallback(index) {
var args = arguments;
returnfunction() {
window['action' + index].apply(null, [].slice.call(args, 1));
}
}
So helpCallback(1, "foo");
would return a function that calls action1('foo')
Solution 5:
I wouldn't personally bother with creating IDs and then referencing them. Why not use closures within bindings to actual elements you've created.
For example, you can do something like
functioncreateLinks() {
var $container = $("#container");
for (var i=0; i < 4; i++) {
var link = $('<a href="#link' + i + '">Link_' + i + '</a>');
$container.append(link);
(function(){
var index = i;
link.click(function(){
alert("Do my thing " + index);
});
})();
}
}
createLinks();
Post a Comment for "Event Binding On Dynamically Created Elements And Passing Parameters"