2011-09-14 50 views
-1

所以我相信这是一个简单的问题,但一直没能弄清楚。下面显示了一个创建并添加到“mousedown”事件中的谷歌地图标记的功能。这是为迭代的每个标记创建的。将静态值传递给动态Javascript函数

逃避我的部分位于'pickup pickup(data [i] .id)'下方的第5行,在此函数调用中提交的值始终是最后一次迭代值。我想在创建每个标记时将我正在迭代的静态值粘贴在那里。

for (i in data) { 
    google.maps.event.addListener(marker, 'mousedown', function() { 
     state = PINCH; 
     map.setOptions({draggable: false}); 
     timeoutId = setTimeout(function() { pickupVenue(data[i].id) }, 1000); 
    }); 
} 

----工作结果----

google.maps.event.addListener(marker, 'mousedown', pickupMarker(data[i].Listing.id)); 

function pickupMarker(id) { 
    return function() { 
     state = PINCH; 
     map.setOptions({draggable: false}); 
     timeoutId = setTimeout('pickupVenue('+id+')', 1000); 
    } 
} 
+0

@duante - 我知道你已经选择了一个答案,但我希望你可以看看我的新答案,因为它是一个替代方法,可以使用效用函数使定时器在这些情况下更容易使用。 – jfriend00

+0

@ jfriend00 - 我很感谢你的回答,可能会用它来做一些事情,但帕特里克正是我所期待的。 – duante

回答

2

你需要确保你通过作为事件的功能侦听器在其范围内具有一个变量,该变量引用i在循环中保留的值,而未修改其修改的i

当前在循环中创建的所有函数共享相同的i变量,因此最终调用处理程序时,它们最终都会获得任何值i引用。

在JavaScript中,创建新变量作用域的唯一方法是调用一个函数,并在该函数中创建一个引用所需值的局部变量(或参数)。

像这样:

function createListener(i) { 
    return function() { 
     state = PINCH; 
     map.setOptions({draggable: false}); 
     timeoutId = setTimeout(function() { pickupVenue(data[i].id) }, 1000); 
    }; 
} 

for (i in data) { 
    google.maps.event.addListener(marker, 'mousedown', createListener(i)); 
} 

在这里,我创建了一个createListener()功能,并通过i进去。

因为现在正在createListener()函数内部创建了监听功能,即监听器将引用i在该变量的作用域,这将继续保留任何值它被赋予,当你调用createListener()(除非你的函数修改i)。

Then createListener()返回该侦听器函数,作为第三个参数传递给addListener()

+0

thx真的很喜欢我们的createListener方法...因为我需要在很多地方重用它,所以很容易http://jsfiddle.net/D2Etw/6/ – duante

+0

+1,注意自我,不要与帕特里克争论: ) – Joe

+0

@IAbstract:呃,只是等待那些我完全错误的场合。 :) – user113716

1

增强从IAbstractDownvoteFactor的关闭答案版本:

for (i in data) { 
    google.maps.event.addListener(marker, 'mousedown', function() { 
     state = PINCH; 
     map.setOptions({draggable: false}); 

     var timeoutFn = function(theId) { 
      return function realTimeoutFn() { 
       pickupVenue(theId); // value of "theId" is kept 
      }; 
     }; 

     timeoutId = setTimeout(timeoutFn(data[i].id), 1000); 
    }); 
} 
0

我看到setTimeout()这个问题经常出现,记住正确的闭包语法总是很麻烦,所以我认为我们应该创建一个setTimeoutWithData()实用函数,使它非常简单。所以在这里,它是:

function setTimeoutWithData(rock, fn, t, ctx) { 
    ctx = ctx || window; 
    function localFn() { 
     fn.call(ctx, rock); 
    } 
    return(setTimeout(localFn, t)); 
} 

它有四个参数和返回的timerId:

rock 

这是任何一块将传递到回调的任何类型的数据。如果你想传递大量的数据,你可以让岩石成为一个物体或一个数组。

fn 

这是您的回调函数。将通过岩石,因为它的参数,以便你的回调应该声明如下:function fn(rock) {}

t 

这是毫秒的setTimeout的时间价值,相同的setTimeout。

ctx 

这是唯一的可选参数。如果您希望回调具有特定的this值,则可以使用ctx参数对其进行配置。除此之外,这允许您使用setTimeoutWithData在对象上调用方法,并且适当地设置this,以便使用面向对象编程更容易。如果ctx未通过,则this将设置为window(与setTimeout相同)。

所以,在这里原来的问题的问题将得到解决这样的:

for (i in data) { 
    google.maps.event.addListener(marker, 'mousedown', function() { 
     state = PINCH; 
     map.setOptions({draggable: false}); 
     timeoutId = setTimeoutWithData(data[i].id, function(anID) { pickupVenue(anID) }, 1000); 
    }); 
} 

而且,这里的显示操作这个工具功能的示例应用程序:http://jsfiddle.net/jfriend00/3SUAJ/