如何修复jQuery中的这个常见错误?
我正在研究Javascript中的闭包 . 有一个章节叫做“常见错误”,它把我彻底吹走了。我不知道它到底在说什么 代码如下:如何修复jQuery中的这个常见错误?,jquery,closures,Jquery,Closures,我正在研究Javascript中的闭包 . 有一个章节叫做“常见错误”,它把我彻底吹走了。我不知道它到底在说什么 代码如下: <p id="help">Helpful notes will appear here</p> <p>E-mail: <input type="text" id="email" name="email"></p> <p>Name: <input type="text" id="name" nam
<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email"></p>
<p>Name: <input type="text" id="name" name="name"></p>
<p>Age: <input type="text" id="age" name="age"></p>
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}
}
setupHelp();
此处将显示帮助说明
电邮:
姓名:
年龄:
函数showHelp(帮助){
document.getElementById('help')。innerHTML=help;
}
函数setupHelp(){
var helpText=[
{'id':'email','help':'Your-mail address'},
{'id':'name','help':'Your full name'},
{'id':'age','help':'您的年龄(您必须超过16岁)}
];
对于(var i=0;i
“帮助”中出现的文本将仅显示最后一个帮助“您的年龄(您必须超过16岁)”
解决方案是在setupHelp之外重写showHelp函数
function makeHelpCallback(help) {
return function() {
showHelp(help);
};
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
}
}
setupHelp();
函数makeHelpCallback(帮助){
返回函数(){
showHelp(帮助);
};
}
函数setupHelp(){
var helpText=[
{'id':'email','help':'Your-mail address'},
{'id':'name','help':'Your full name'},
{'id':'age','help':'您的年龄(您必须超过16岁)}
];
对于(var i=0;i
我不明白它为什么能解决这个问题。因为我从不使用javascript访问DOM,而是使用jQuery,所以我在jQuery中重写了该函数
function makeHelpCallback(i) {
return function () {
$("#help").text(i);
};
}
(function () {
var helpText = [
{ 'id': 'email', 'help': 'Your e-mail address' },
{ 'id': 'name', 'help': 'Your full name' },
{ 'id': 'age', 'help': 'Your age (you must be over 16)' }
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
$("#"+item.id).focus(function () {
new makeHelpCallback(item.help)();
});
}
})();
函数makeHelpCallback(i){
返回函数(){
$(“#帮助”).text(i);
};
}
(功能(){
var helpText=[
{'id':'email','help':'Your-mail address'},
{'id':'name','help':'Your full name'},
{'id':'age','help':'您的年龄(您必须超过16岁)}
];
对于(var i=0;i
但是虫子并没有消失。据我所知,jQuery没有onfocus处理程序,不可能将处理程序绑定到同一级别的侦听器。它必须在函数(){}下运行。我无法达到Javascript所能达到的效果
那么,是否有必要编写与Javascript代码等效的代码
正如解释所说,这不起作用,因为听众共享相同的环境。不管它是什么意思,onfocus=function(){showHelp(item.help)}分别执行了三次。它们应该受到相应的约束。为什么他们会出现相同的结果?因为showHelp是一个静态对象?如果是这样,添加一个新的修改器应该可以完成这项工作。和makeHelpCallback(item.help)也共享相同的环境。但它是有效的。
为什么
为了便于测试,附上完整的HTML代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<p id="help">Helpful notes will appear here</p>
<p>E-mail:
<input type="text" id="email" name="email"></p>
<p>Name:
<input type="text" id="name" name="name"></p>
<p>Age:
<input type="text" id="age" name="age"></p>
<script src="Scripts/jquery-1.9.1.min.js"></script>
<script>
function makeHelpCallback(i) {
return function () {
$("#help").text(i);
};
}
(function () {
var helpText = [
{ 'id': 'email', 'help': 'Your e-mail address' },
{ 'id': 'name', 'help': 'Your full name' },
{ 'id': 'age', 'help': 'Your age (you must be over 16)' }
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
$("#" + item.id).focus(function () {
makeHelpCallback(item.help)();
});
}
})();
</script>
</body>
</html>
此处将显示帮助说明
电邮:
姓名:
年龄:
函数makeHelpCallback(i){
返回函数(){
$(“#帮助”).text(i);
};
}
(功能(){
var helpText=[
{'id':'email','help':'Your-mail address'},
{'id':'name','help':'Your full name'},
{'id':'age','help':'您的年龄(您必须超过16岁)}
];
对于(var i=0;i
我会在下面给你答案,但我建议你试着自己找出答案。一些提示:
您到底要将什么传递给focus
方法
函数的变量是如何定义的?请记住,您需要了解函数何时执行
在代码中:
$("#"+item.id).focus(function () {
new makeHelpCallback(item.help)();
});
将函数传递给focus
,在循环完成且item
变量设置为最后一项后,稍后(当焦点事件发生时)调用此函数。您应该做的是,传递一个带有自己的局部变量的函数,该局部变量在调用focus
时绑定。这就是makeHelpCallback
的全部要点!您的代码应该如下所示:
$("#"+item.id).focus(makeHelpCallback(item.help));
makeHelpCallback
返回一个函数,在这里,如果您更清楚的话,将其全部内联编写:
$("#"+item.id).focus((function (i) {
// this function is executed immediately
// i is bound to the correct item.
return function () {
$("#help").text(i);
};
})());
一个简单的例子更容易理解:
var i;
var funcsToRun = [];
for (i = 0; i < 3; ++i) {
funcsToRun.push(function() { alert(i); });
}
funcsToRun[0](); // "3"
funcsToRun[1](); // "3"
funcsToRun[2](); // "3"
vari;
var funcsToRun=[];
对于(i=0;i<3;++i){
push(函数(){alert(i);});
}
funcsToRun[0]();//"3"
funcsToRun[1]();//"3"
funcsToRun[2]();//"3"
这是因为警报使用的“i”是闭包的一部分,并且被固定在变量“i”上,该变量在执行函数时的值为3。但是:
var i;
var funcsToRun = [];
for (i = 0; i < 3; ++i) {
funcsToRun.push(
(function(idx) {
return function() { alert(idx); };
})(i)
);
}
funcsToRun[0](); // "0"
funcsToRun[1](); // "1"
funcsToRun[2](); // "2"
vari;
var funcsToRun=[];
对于(i=0;i<3;++i){
功能推送(
(功能(idx){
返回函数(){alert(idx);};
})(一)
);
}
funcsToRun[0]();//"0"
funcsToRun[1]();//"1"
funcsToRun[2]();//"2"
这是因为您没有将警报附加到变量“i”上,而是将其附加到“idx”上,该变量在循环内部立即作为“i”的值进行计算,而不是在循环之后。因此,内部函数立即运行,但只返回另一个函数alert(0)
,而不是alert(i)
使用这种思路,您可以将其应用于更大的示例。感谢Joe提供了简化的示例。我想我能抓住它。 我试着把乔的例子放进程序序列中。让我知道我错了
var i;
var funcsToRun = [];
//for loop begins
i = 0
//i = 0
funcsToRun.push(function() { alert(i); }); // function(){ alert(i)} is not executed. i remains i.
i++ //i = 1
funcsToRun.push(function() { alert(i); });
i++ //i = 2
funcsToRun.push(function() { alert(i); });
i++ //i = 3 loop stopped. although the for loop completes, i remains in memory. It is not destroyed albeit its completion.
funcsToRun[0](); // function(){alert(i)} executes this moment, and i is 3 now.
funcsToRun[1](); // "3"
funcsToRun[2](); // "3"
最后我用jQuery实现了这个结果
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<p id="help">Helpful notes will appear here</p>
<p>
E-mail:
<input type="text" id="email" name="email">
</p>
<p>
Name:
<input type="text" id="name" name="name">
</p>
<p>
Age:
<input type="text" id="age" name="age">
</p>
<script src="Scripts/jquery-1.9.1.min.js"></script>
<script>
(function () {
var helpText = [
{ 'id': 'email', 'help': 'Your e-mail address' },
{ 'id': 'name', 'help': 'Your full name' },
{ 'id': 'age', 'help': 'Your age (you must be over 16)' }
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
$("#" + item.id).focus(function (msg) {
return function () { $("#help").text(msg); }
}(item.help));
}
})();
</script>
</body>
</html>
此处将显示帮助说明
电邮:
姓名: