2011-02-16 59 views
0

我想創建一個個性化的表情符號系統trein我的JavaScript。 爲了實現這一點,我有一個離線系統來保存各種用戶表情符號(我只保存網址)。笑臉系統:事件添加圖像在文本區失敗

獲取數據後,我嘗試將它們顯示在我想要的textarea上方。到現在爲止還挺好!

現在,問題出現在將事件添加到圖像的時候了。 我嘗試爲每個圖像添加事件偵聽器,但無論哪個圖像只按最後一個圖像事件觸發。

這是:所有圖像正確並排顯示,但在textarea中插入的內容是循環中最後一次迭代的圖像。

有意義代碼:

/* Insert the code in the right place in the textarea*/ 
function putInTxtarea(text, textarea) { 
    // Mozilla text range replace. 
    if (typeof(textarea.selectionStart) != "undefined") { 
     var begin = textarea.value.substr(0, textarea.selectionStart); 
     var end = textarea.value.substr(textarea.selectionEnd); 
     var scrollPos = textarea.scrollTop; 
     textarea.value = begin + text + end; 

     if (textarea.setSelectionRange) 
     { 
      textarea.focus(); 
      textarea.setSelectionRange(begin.length + text.length, begin.length + text.length); 
     } 
     textarea.scrollTop = scrollPos; 
    } 
    // Just put it on the end. 
    else { 
     textarea.value += text; 
     textarea.focus(textarea.value.length - 1); 
    } 


var elem = document.createElement("div"); 
elem.id = "mySmilies"; 
elem.innerHTML = ""; 

for each (url in smiliesUrl){ 
    var img = document.createElement("img"); 
    img.src = url; 
    img.style.cursor = "pointer"; 
    img.addEventListener('click', 
     function(){putInTxtarea('[img]'+url+'[/img]', document.getElementsByName('message')[0]); 
       };, false); // here is the event attaching 

    elem.appendChild(img); 
} 

回答

1

不要使用for each...in。這是一個只在Firefox中可用的構造(至少它是非標準的)。

您正在使典型的創建一個功能在一個循環錯誤。 JavaScript只有函數範圍。在循環中創建的每個函數都引用相同的變量(在您的情況下爲url),並且此變量將具有循環完成後最後一個URL的值。您需要引入一個新的範圍:

function createClickHandler(url) { 
    var target = document.getElementsByName('message')[0]; 
    return function() { 
     putInTxtarea('[img]'+url+'[/img]', target); 
    } 

} 

// assuming smiliesUrl is an array 
for(var i = smiliesUrl.length;i--;) { 
    var url = smiliesUrl[i]; 
    var img = document.createElement("img"); 
    img.src = url; 
    img.style.cursor = "pointer"; 
    img.addEventListener('click', createClickHandler(url), false); 
    elem.appendChild(img); 
} 

另一種可能是簡單地從事件處理程序訪問圖像。 It should available via this

img.addEventListener('click', function(){ 
    putInTxtarea('[img]'+this.src+'[/img]', 
        document.getElementsByName('message')[0]); 
};, false); 
0

這接縫是一個閉合的問題。變量url指向循環中使用的url,並且在執行時它始終是最後一個url。

for(url in smiliesUrl){ 
    var img = document.createElement("img"); 
    img.src = url; 
    img.style.cursor = "pointer"; 
    var func = function(jUrl){ 
     return function(){ 
      putInTxtarea('[img]' + jUrl + '[/img]', 
      document.getElementsByName('message')[0]); 
     }; 
    }(url); 
    img.addEventListener('click', func, false); 
} 

更多關於關閉JavaScript中看到This question

+0

這就是我一直在尋找的東西。只需要一個函數內部的函數來創建一個新的變量。謝謝。 – brunoais 2011-02-16 09:00:06

+0

@ user551625:但是不要使用`for ... in`來遍歷數組。使用普通的`for`循環。 – 2011-02-16 09:26:28