2011-09-14 46 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/