Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解javascript列表适配器中的作用域_Javascript_Jquery_Html_Scope - Fatal编程技术网

了解javascript列表适配器中的作用域

了解javascript列表适配器中的作用域,javascript,jquery,html,scope,Javascript,Jquery,Html,Scope,我正在动态创建按钮列表,并将它们附加到span中。每个按钮都与通过ajax下载的JSON数据相关联。数据显然在工作,但是我的jQuery单击事件没有获得正确的索引数据。也就是说,应该与该单元格关联的数据不是-我单击的任何单元格实际上都只对应于列表中最后一个元素的数据。更清楚地说,以下是我拥有的(或可用的小提琴): JSON数据 var data = [{"id":0, "name":"Phil"}, {"id":1, "name":"Ed"}, {"id":2, "name":"Fred"}]

我正在动态创建
按钮列表
,并将它们附加到
span
中。每个按钮都与通过ajax下载的JSON数据相关联。数据显然在工作,但是我的
jQuery
单击事件没有获得正确的索引数据。也就是说,应该与该单元格关联的数据不是-我单击的任何单元格实际上都只对应于列表中最后一个元素的数据。更清楚地说,以下是我拥有的(或可用的小提琴):

  • JSON数据

    var data = [{"id":0, "name":"Phil"}, {"id":1, "name":"Ed"}, {"id":2, "name":"Fred"}];
    
  • HTML文件

    <span id="output"></span><br>
    
  • 代码

    for (var i = 0; i < data.length; i++) {
        var person = data[i];
        var button = document.createElement('button');
        button.type = 'button';
        $(button).addClass('listButton');
        var text = "<b>ID:</b> " + person.id + "<br>";
        text = text + "<b>Name:</b> " + person.name;
        $(button).html(text);
        $(button).click(function() {
            alert("selected person: " + person.id);//always 2, no matter who is clicked.
        });
        document.getElementById("output").appendChild(button);
    }
    
    for(变量i=0;i”;
    text=text+“Name:”+person.Name;
    $(按钮).html(文本);
    $(按钮)。单击(函数(){
    警报(“所选人员:+person.id);//始终为2,无论单击的是谁。
    });
    document.getElementById(“输出”).appendChild(按钮);
    }
    
  • 结果

(单击任意单元格以查看警报“所选人员:2”)


我的第一个想法是这是一个范围问题——这意味着每次我创建一个新按钮时,它都在为其他每个单元格更新按钮。我的第一次修复尝试是在主for循环中设置jQuery数据:
$(button.data(“id”,person.id),然后将其返回到单击函数中:
$(按钮)。数据(“id”)
。不用说,这是行不通的


我做错了什么,如何修复它?

这就是JavaScript中作用域的工作原理。像
if
这样的条件和像
for
这样的循环没有作用域,除了深奥的情况外,只有函数作用域

这个问题在初学者中很常见

您没有循环作用域,您的警报绑定到
,循环结束时是第三个人

如果希望每个处理程序对相应的人做出反应,则需要“关闭”事件处理程序中的人

(function(person){
    $(button).click(function() {
            alert("selected person: " + person.id);//correct value!
    });
})(person); // close over the person
我们正在创建一个包装处理程序的函数,它跟踪传递给它的
person
的值,以便处理程序知道在什么值上运行

另一种方法是使用,它将对数组中的每个
人运行一个函数,有效地创建范围

这将类似于:

data.forEach(function(person){
    var button = document.createElement('button');
    button.type = 'button';
    $(button).addClass('listButton');
    var text = "<b>ID:</b> " + person.id + "<br>";
    text = text + "<b>Name:</b> " + person.name;
    $(button).html(text);
    $(button).click(function() {
        alert("selected person: " + person.id);
    });
    document.getElementById("output").appendChild(button);
});
HTML:


ID:
姓名:
这就是JavaScript中作用域的工作原理。像
if
这样的条件和像
for
这样的循环没有作用域,除了深奥的情况外,只有函数作用域

这个问题在初学者中很常见

您没有循环作用域,您的警报绑定到
,循环结束时是第三个人

如果希望每个处理程序对相应的人做出反应,则需要“关闭”事件处理程序中的人

(function(person){
    $(button).click(function() {
            alert("selected person: " + person.id);//correct value!
    });
})(person); // close over the person
我们正在创建一个包装处理程序的函数,它跟踪传递给它的
person
的值,以便处理程序知道在什么值上运行

另一种方法是使用,它将对数组中的每个
人运行一个函数,有效地创建范围

这将类似于:

data.forEach(function(person){
    var button = document.createElement('button');
    button.type = 'button';
    $(button).addClass('listButton');
    var text = "<b>ID:</b> " + person.id + "<br>";
    text = text + "<b>Name:</b> " + person.name;
    $(button).html(text);
    $(button).click(function() {
        alert("selected person: " + person.id);
    });
    document.getElementById("output").appendChild(button);
});
HTML:


ID:
姓名:
当您编写以下内容时:

 function() {
   for (var i = 0; i < 10; i++) {
      var k = i;
   }
 }
function() {
   var k, i;
   for (i=0; i<10; i++) {
      k=i;
   }
}
当你写这篇文章时:

 function() {
   for (var i = 0; i < 10; i++) {
      var k = i;
   }
 }
function() {
   var k, i;
   for (i=0; i<10; i++) {
      k=i;
   }
}

但这里的问题并不是提升,而是在标准循环/条件构造中没有块作用域。答案似乎是正确的。@BenjaminGruenbaum:正确。删除了那行-我需要停止多任务。谢谢你的解释-这真的很有帮助!但这里的问题并不是提升,而是在标准循环/条件构造中没有块作用域。答案似乎是正确的。@BenjaminGruenbaum:正确。删除了那行-我需要停止多任务。谢谢你的解释-这真的很有帮助!下面是一个使用
.data()
:)@Bondye
的工作示例。data
是一种可怕的破坏性方法,违反了关注点分离。您将DOM作为知识的来源,而不是JavaScript对象和JSON数据。请参阅我回答中的“我将如何做”部分。下面是一个使用
.data()
:)@Bondye
的工作示例。data
是一种可怕的破坏性方法,违反了关注点分离。您将DOM作为知识的来源,而不是JavaScript对象和JSON数据。请看我回答中的“我将如何做”部分。这是一个很好的回答-它涉及到我做错了什么,我如何修复它,甚至进一步解释了我如何从整体上改进代码。谢谢你的详尽回答@Phil不客气,请考虑删除,它只是处理数据绑定,让你专注于重要的事情,编写HTML一样的HTML,JavaScript,如JavaScript,并告诉它什么是绑定到什么。这是一个非常好的资源:)好运气这是一个很好的回答-它涉及到我做错了什么,我如何修复它,甚至进一步解释了我如何从整体上改进代码。谢谢你的详尽回答@Phil不客气,请考虑删除,它只是处理数据绑定,让你专注于重要的事情,编写HTML一样的HTML,JavaScript,如JavaScript,并告诉它什么是绑定到什么。这是一个非常好的资源:)祝你好运
for (var i = 0; i < data.length; i++) {
 (function(person) {
  var button = document.createElement('button');
  button.type = 'button';
  $(button).addClass('listButton');
  var text = "<b>ID:</b> " + person.id + "<br>";
  text = text + "<b>Name:</b> " + person.name;
  $(button).html(text);
  $(button).click(function() {
    alert("selected person: " + person.id);//always 2, no matter who is clicked.
  });
  document.getElementById("output").appendChild(button);
 })(data[i]);
}