2013-10-31 65 views
1

我想動態地創建一個按鈕,它將從對象中刪除一個鍵。但是,在這一點上,我只是簡單地使用警報來測試正確的值,稍後將傳遞給將放棄密鑰的函數。我正在運行一個for-in循環,我試圖將迭代器傳遞給循環中調用的函數。問題是alert語句正在使用迭代器'i',並且隨着循環結束,此警報的所有實例都被更改爲'i'的最終值。 (我希望是有道理的!)Javascript使用for-in循環迭代器來設置變量

locations = {}; 

function Location(nickname, address) { 
    this.nickname = nickname; 
    this.address = address; 
} 

Location.prototype.showLocations = function() { 
    var x=document.getElementById("demo"); 
    output = "<table><tr><th>Location</th><th>Address</th><th>Delete</th></tr>"; 
    for (i in locations) (function(i) 
    { 
     output+=listThis(i);   

    }) (i); 
    // for (i in locations) { 
    //  output+=listThis(i); 
    //  } 
    output+="</table>" 
    x.innerHTML=output; 
} 

function listThis(i){ 
    thisLoc = locations[i].nickname; 
    var thisOutput="<tr><td>"+locations[thisLoc].nickname+"</td><td>"+locations[thisLoc].address+"</td><td><input type='button' value='X' onclick='alert(locations[thisLoc].nickname)' /></td></tr>"; 
    return thisOutput; 
} 

function enterLocation() { 
    var address = document.getElementById('address').value; 
    var nickname = document.getElementById('nickname').value; 
    locations[nickname] = new Location(nickname, address); 
    locations[nickname].showLocations(); 
} 

標記是:

<p id="demo">Table to go in here.</p> 
<div id="panel"> 
    <input id="nickname" type="textbox" placeholder="Location Name" /> 
    <input id="address" type="textbox" placeholder="Sydney, NSW" /> 
    <input type="button" value="Enter" onclick="enterLocation()" /> 
</div> 

請注意,我試圖用這個帖子Javascript - how to work with the iterator in a for loop with callbacks發現信息工作,但都沒有成功。你會看到另一個for循環評論說,我最初嘗試。

+0

不要在JavaScript中生成HTML;只是操縱DOM而已。另外,你可以添加一個[jsFiddle](http://jsfiddle.net/)或類似的顯示問題嗎? – Ryan

+0

問題是全局'thisLoc',而不是'i'。 – bfavaretto

+0

請停止使用全局變量。在本地聲明你的變量。 – jfriend00

回答

2

問題出在內聯onclick處理程序。

你寫onclick='alert(locations[thisLoc].nickname)'這裏thisLoc不是你的變量的直接引用。它是在運行時評估的一些名稱。

在線thisLoc = locations[i].nickname;您定義了global變量thisLoc,該值在每次迭代時被覆蓋。然後當onclick被處理時,訪問具有(總是)最新值的全局變量。

有很多種解決方案是:

  • 不要使用HTML作爲建設MiniTech移動說 - 使用DOM操作
  • 寫值一些DOM屬性,同時建立並在onclick處理器閱讀:

    "<input type='button' value='X' data-location-name="' + thisLoc + '" onclick='alert(locations[this.getAttribute('data-location-name')].nickname)' />" 
    
+0

爲什麼使用該值設置屬性而不是直接設置要提醒的值? –

0

正如其他人所說,你需要正確範圍的變量(即不使用全局變量)。

var locations = {}; 

function Location(nickname, address) { 
    this.nickname = nickname; 
    this.address = address; 
} 

Location.prototype.showLocations = function() { 
    var x = document.getElementById("demo"); 
    var output = "<table><tr><th>Location</th>" + 
     "<th>Address</th><th>Delete</th></tr>"; 
    for (var i in locations) { 
    output += listThis(i); 
    } 

    output += "</table>"; 
    x.innerHTML = output; 
}; 

function listThis(i){ 
    var thisLoc = locations[i].nickname; 
    var thisAddr = locations[i].address; 
    var thisOutput= "<tr><td>" + thisLoc + "</td><td>" + thisAddr + 
     "</td><td><input type='button' value='X' onclick='alert(\"" + 
     thisLoc + "\")' /></td></tr>"; 
    return thisOutput; 
} 

function enterLocation() { 
    var address = document.getElementById('address').value; 
    var nickname = document.getElementById('nickname').value; 
    locations[nickname] = new Location(nickname, address); 
    locations[nickname].showLocations(); 
} 

Here's a fiddle with the updated code

需要注意的是,該代碼仍然在將locations變量和所有函數添加到全局範圍,這不是推薦的做法。解決您的問題所需的唯一更改是修復在您的函數中定義和使用的變量的範圍。

+0

因此,如果不在'locations'全局變量中,我應該如何存儲位置?我應該使用localStorage嗎? – Khrys