I tried debugging my code for like a few hour but I got nothing out of it. The issue is that it makes absolutely no sense on why it reports an error every time I tried to use document.forms[0][i] (i as the iterator) in the event listener but "this" satisfies the code.
//broken
var addListeners = function() {
var i;
var formFields = document.forms[0];
var formSubmit = formFields["submit"];
for (i = 0; i < formFields.length; i++) {
if (formFields[i] != formSubmit) {
formFields[i].onblur = (function () {
checkNonEmpty(formFields[i]);
});
}
}
};
//works
var addListeners = function() {
var i;
var formFields = document.forms[0];
var formSubmit = formFields["submit"];
for (i = 0; i < formFields.length; i++) {
if (formFields[i] != formSubmit) {
formFields[i].onblur = (function () {
checkNonEmpty(this);
});
}
}
};
Wouldn't "this" refer to document.forms[0][i]?... formFields references to document.forms[0]. However the exact same code (with "this" where formFields[i] is at) works just fine.
Here is the demo: /
I tried debugging my code for like a few hour but I got nothing out of it. The issue is that it makes absolutely no sense on why it reports an error every time I tried to use document.forms[0][i] (i as the iterator) in the event listener but "this" satisfies the code.
//broken
var addListeners = function() {
var i;
var formFields = document.forms[0];
var formSubmit = formFields["submit"];
for (i = 0; i < formFields.length; i++) {
if (formFields[i] != formSubmit) {
formFields[i].onblur = (function () {
checkNonEmpty(formFields[i]);
});
}
}
};
//works
var addListeners = function() {
var i;
var formFields = document.forms[0];
var formSubmit = formFields["submit"];
for (i = 0; i < formFields.length; i++) {
if (formFields[i] != formSubmit) {
formFields[i].onblur = (function () {
checkNonEmpty(this);
});
}
}
};
Wouldn't "this" refer to document.forms[0][i]?... formFields references to document.forms[0]. However the exact same code (with "this" where formFields[i] is at) works just fine.
Here is the demo: http://jsfiddle/PbHwy/
Share Improve this question edited Jun 16, 2012 at 8:24 Codist asked Jun 16, 2012 at 8:13 CodistCodist 1,2082 gold badges12 silver badges29 bronze badges 2- Please post the exact error message. It also helps if you provide a little demo. You can use http://jsfiddle for this. – Zeta Commented Jun 16, 2012 at 8:17
- When the onblur event occurs on the form field... Here is the error that pops up in the dev console "Uncaught TypeError: Cannot read property 'value' of undefined". – Codist Commented Jun 16, 2012 at 8:19
3 Answers
Reset to default 3Cranio's answer already contains the root of the matter. To get rid of this you can either include formFields[i]
by using closures
var blurCallbackGenerator = function(element){
return function () {
checkNonEmpty(element);
};
};
formFields[i].onblur = blurCallbackGenerator(formFields[i]);
/* // dense version:
formFields[i].onblur = (function(element){
return function () {
checkNonEmpty(element);
};
})(formFields[i]);
*/
or simply using this
.
See also:
- MDN: Creating closures in loops: A mon mistake
Because you define formFields
in a scope outside (or better, different than) the event listener. When the event listener is called, it is called not in the addListeners
function where you define formFields
, but "independently", so the reference is lost and its value is undefined (but this
works because it is not dependent on that scope).
The problem is that the variable i
(referred to in each of your handlers) is the exact same variable in each of them, which by the time the loop has finished has value formFields.length+1
and is therefore wrong for all of them. Try this instead [note: the below used to say something VERY WRONG before I edited it -- thanks to Zeta for pointing out my mistake]:
var addListeners = function() {
var i;
var formFields = document.forms[0];
var formSubmit = formFields["submit"];
for (i = 0; i < formFields.length; i++) {
if (formFields[i] != formSubmit) {
formFields[i].onblur = (function(j) {
return (function () {
checkNonEmpty(formFields[j]);
})(i);
});
}
}
};
and you'll find it works (unless there's another bug that I haven't noticed).
If you can afford to support only Javascript 1.7 and above, you can instead write your old code but make your for
look like this: for (let i=0; i<formFields.length; i++)
. But you quite possibly can't.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745605381a4635643.html
评论列表(0条)