Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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_Javascript Events - Fatal编程技术网

Javascript-作用域问题并将参数传递给动态创建的事件处理程序

Javascript-作用域问题并将参数传递给动态创建的事件处理程序,javascript,javascript-events,Javascript,Javascript Events,在下面的代码中,您将看到我正在尝试为image.onclick定义一个事件处理程序,它需要额外的参数,我在while循环中声明了这些参数,希望javascript以这种方式定义作用域,但事实并非如此。基本上,这里所有的事件处理程序都得到了我给变量id和section_id的最后一个值。你知道如何处理动态生成这些处理程序的情况吗 function handlePicturesResult(){ if (req.readyState == 4) { // Complete i

在下面的代码中,您将看到我正在尝试为image.onclick定义一个事件处理程序,它需要额外的参数,我在while循环中声明了这些参数,希望javascript以这种方式定义作用域,但事实并非如此。基本上,这里所有的事件处理程序都得到了我给变量id和section_id的最后一个值。你知道如何处理动态生成这些处理程序的情况吗

function handlePicturesResult(){
    if (req.readyState == 4) { // Complete
        if (req.status == 200) { // OK response

            var el = document.getElementById('pictureHolder');
            while( el.hasChildNodes() ){
                el.removeChild(el.lastChild);
            }

            var tempObject = JSON.parse(req.responseText);
            var pictures = tempObject.images;
            var i=0;

            while(i<pictures.length){

                var picIndex = i;

                var image= new Image(120,80);
                image.src = 'images/' + pictures[i].url;
                image.width = 120;
                image.height = 80;
                var id = pictures[picIndex].id;
                var section_id = pictures[picIndex].sectionId;
                image.onclick = function(event){
                    deleteImage(event,id,section_id);
                }


                var txtNode = document.createTextNode(pictures[picIndex.valueOf()].id); 
                el.appendChild(image);
                el.appendChild(txtNode);
                i++;
            }
        } else {
        alert("Problem: " + req.statusText);
        }
    }

}
函数handlePicturesResult(){
如果(req.readyState==4){//完成
如果(请求状态==200){//OK响应
var el=document.getElementById('pictureHolder');
while(el.hasChildNodes()){
el.removeChild(el.lastChild);
}
var tempObject=JSON.parse(req.responseText);
var pictures=tempObject.images;
var i=0;

而(我又是一个问题被解决了

外部函数立即运行(注意末尾带有参数的括号),并返回内部函数,该函数在其范围内保留变量的副本,就像循环迭代时一样

JavaScript按值传递非对象变量,因此通过将
id
section_id
传递给外部函数,您可以在该函数内创建它们的副本。当您创建并返回内部函数时,该内部函数将在创建时在范围内的所有变量保留在范围内(这是,包括
id
section\u id
的局部变量副本。具有唯一作用域的内部函数成为该元素的事件处理程序。

您需要使用闭包。

javascript中的作用域可以在函数的大括号内定义,这就是为什么让外部函数执行并向其传递参数将在循环中的特定时间保留这些变量的值


如果没有它们,id和section_id的值将始终引用它们在上一次迭代中拥有的值。

这是一个典型的JavaScript问题,源于对函数范围缺乏了解。在这一行:

deleteImage(event,id,section_id);
传递给
deleteImage
的参数没有理由保留它们在创建回调时的值。变量
id
section\u id
绑定到
handlePicturesResult
的范围;它们是存在于该空间中的变量,并且只有一个si因此,当回调运行时,它将使用这些特定变量和它们当前引用的值(来自循环的上一次迭代)

解决方案是将变量放入一个作用域,在循环的每次迭代中“保存”它们的值。函数在JS中只提供这样的作用域。我不会重复已经提供的优秀解决方案。另一种方法是在迭代中使用jQuery,这样您就不会再遇到这个问题:

$.each(pictures, function(i, picture) {

    var image= new Image(120,80);
    var id = pictures.id;
    var section_id = picture.sectionId;
    var txtNode = document.createTextNode(id);

    image.width = 120;
    image.height = 80;
    image.src = 'images/' + picture.url;

    image.onclick = function(event){
        deleteImage(event, id, section_id);
    }

    el.appendChild(image);
    el.appendChild(txtNode);

});
  • 假设
    pictures
    是一个数组

对不起,我现在不知道该怎么做:)
deleteImage(event,id,section_id);
$.each(pictures, function(i, picture) {

    var image= new Image(120,80);
    var id = pictures.id;
    var section_id = picture.sectionId;
    var txtNode = document.createTextNode(id);

    image.width = 120;
    image.height = 80;
    image.src = 'images/' + picture.url;

    image.onclick = function(event){
        deleteImage(event, id, section_id);
    }

    el.appendChild(image);
    el.appendChild(txtNode);

});