I have this code:
document.getElementById('img'+i).onclick = function(){popup_show('popup',array_msg[i]+''+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict, 'AddEditSchedule;;popup_drag2;;EditSched;;'+String(array_msg_id[3])+';;view', 'popup_drag', 'popup_exit', 'screen-center', 0, 0);};
...but when I click on the image, the data of array_msg[i]
is the last data of the loop, meaning the index is the length of the loop. I use IE for this.
Please give me an idea on how to do this. In FF, it works fine because I use setAttribute
.
@bobince
document.getElementById('img'+i).onclick= popup_show.bind(window, 'popup',array_msg[i]+''+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict,'AddEditSchedule;;popup_drag2;;EditSched;;'+array_msg_id[3]+';;view','popup_drag', 'popup_exit', 'screen-center', 0, 0 );
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
I have this code:
document.getElementById('img'+i).onclick = function(){popup_show('popup',array_msg[i]+''+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict, 'AddEditSchedule;;popup_drag2;;EditSched;;'+String(array_msg_id[3])+';;view', 'popup_drag', 'popup_exit', 'screen-center', 0, 0);};
...but when I click on the image, the data of array_msg[i]
is the last data of the loop, meaning the index is the length of the loop. I use IE for this.
Please give me an idea on how to do this. In FF, it works fine because I use setAttribute
.
@bobince
document.getElementById('img'+i).onclick= popup_show.bind(window, 'popup',array_msg[i]+''+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict,'AddEditSchedule;;popup_drag2;;EditSched;;'+array_msg_id[3]+';;view','popup_drag', 'popup_exit', 'screen-center', 0, 0 );
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
Share
edited Jan 8, 2010 at 7:29
Treby
asked Jan 8, 2010 at 6:07
TrebyTreby
1,3206 gold badges18 silver badges26 bronze badges
5 Answers
Reset to default 2Treby, this is cleaned up version of your answer. The additional anonymous anonymous function that you added isn't necessary.
for (var i = 0, l = array.length; i < l; i++ ) {
document.getElementById(i + '05').onclick = (function(tmp) {
return function() {
popup_show(
"popup",
array_msg[tmp] + '' + date('Y-m-d', strtotime(lec_date)) + '-==-' + str_view_forConflict,
"AddEditSchedule;;popup_drag2;;EditSched;;" + String(array_msg_id[3]) + ";;view",
"popup_drag", "popup_exit", "screen-center", 0, 0
);
};
})(i);
}
Edited to fix closure issue
You've hit the loop-variable-closure problem. This is a very mon gotcha in C-style languages with closures, such as JavaScript and Python. See the accepted answer of this question for a solution involving binding the loop variables in a second closure.
A slightly less nested solution is to use function.bind()
:
for (var i= 0; i<something.length; i++) {
document.getElementById('img'+i).onclick= popup_show.bind(window, 'popup',
array_msg[i]+''+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict,
'AddEditSchedule;;popup_drag2;;EditSched;;'+array_msg_id[3]+';;view',
'popup_drag', 'popup_exit', 'screen-center', 0, 0
);
}
however since this method is an ECMAScript Fifth Edition feature not supported by most browsers yet it needs a little help — see the bottom of this answer for a backwards-patible implementation.
You need to use a closure. It would help if you provided the loop code as well as the code that is executed in the loop, but assuming you have a standard for
loop iterating through an array, the following code should work:
for (var i = 0, l = array.length; i < l; i++)
{
(function(i) {
document.getElementById("img" + i).addEventListener("click", function() {
popup_show("popup", array_msg[i] + "" + date("Y-m-d", strtotime(lec_date)) + "-==-" + str_view_forConflict, "AddEditSchedule;;popup_drag2;;EditSched;;" + String(array_msg_id[3]) + ";;view", "popup_drag", "popup_exit", "screen-center", 0, 0);
}, false);
})(i);
}
Also, you shouldn't be using setAttribute
in Firefox. Instead, use element.onclick
or, preferably, element.addEventListener
, which allows you to add multiple functions to be called when an event fires and thus this plays nicely with other code (if two bits of code assign a function to, say, a click event in the form element.onclick = function() { ...
, then the second assignment overrides the first—not good). I've used element.addEventListener
in my code example above.
Closures. You need to use JavaScript Closures. See if answers to this question help.
Working Answer:
var closures = [];
for (var i = 0; i < array.length; i++){
closures[i] = (function(tmp) {
return function() {
document.getElementById(tmp + '05').onclick = function(){popup_show("popup", array_msg[tmp]+''+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict, "AddEditSchedule;;popup_drag2;;EditSched;;"+ String(array_msg_id[3]) +";;view", "popup_drag", "popup_exit", "screen-center", 0, 0)};
};
})(i);
closures[i]();
}
Thanks to Steve Harrison Answer. I got an idea to wrap around it