2013-06-29 34 views
51

我正在嘗試使userscript爲網站添加自定義表情。但是,我收到了很多錯誤。未捕獲的ReferenceError:函數未使用onclick定義

下面是函數:

function saveEmotes() { 
    removeLineBreaks(); 
    EmoteNameLines = EmoteName.value.split("\n"); 
    EmoteURLLines = EmoteURL.value.split("\n"); 
    EmoteUsageLines = EmoteUsage.value.split("\n"); 

    if (EmoteNameLines.length == EmoteURLLines.length && EmoteURLLines.length == EmoteUsageLines.length) { 
     for (i = 0; i < EmoteURLLines.length; i++) { 
      if (checkIMG(EmoteURLLines[i])) { 
       localStorage.setItem("nameEmotes", JSON.stringify(EmoteNameLines)); 
       localStorage.setItem("urlEmotes", JSON.stringify(EmoteURLLines)); 
       localStorage.setItem("usageEmotes", JSON.stringify(EmoteUsageLines)); 
       if (i == 0) { 
        console.log(resetSlot()); 
       } 
       emoteTab[2].innerHTML += '<span style="cursor:pointer;" onclick="appendEmote(\'' + EmoteUsageLines[i] + '\')"><img src="' + EmoteURLLines[i] + '" /></span>'; 
      } else { 
       alert("The maximum emote(" + EmoteNameLines[i] + ") size is (36x36)"); 
      } 
     } 
    } else { 
     alert("You have an unbalanced amount of emote parameters."); 
    } 
} 

span標籤的onclick調用此函數:

function appendEmote(em) { 
    shoutdata.value += em; 
} 

我每次點擊一個具有onclick屬性的按鈕,我得到這個錯誤:

Uncaught ReferenceError: function is not defined.

任何幫助,將不勝感激。

謝謝!

更新

我試着使用:

emoteTab[2].innerHTML += '<span style="cursor:pointer;" id="'+ EmoteNameLines[i] +'"><img src="' + EmoteURLLines[i] + '" /></span>'; 
document.getElementById(EmoteNameLines[i]).addEventListener("click", appendEmote(EmoteUsageLines[i]), false); 

但我得到了一個undefined錯誤。

這裏是script

我想這樣做是爲了測試是否監聽工作,他們不這樣做對我來說:

emoteTab[2].innerHTML = '<td class="trow1" width="12%" align="center"><a id="togglemenu" style="cursor: pointer;">Custom Icons</a></br><a style="cursor: pointer;" id="smilies" onclick=\'window.open("misc.php?action=smilies&amp;popup=true&amp;editor=clickableEditor","Smilies","scrollbars=yes, menubar=no,width=460,height=360,toolbar=no");\' original-title="">Smilies</a><br><a style="cursor: pointer;" onclick=\'window.open("shoutbox.php","Shoutbox","scrollbars=yes, menubar=no,width=825,height=449,toolbar=no");\' original-title="">Popup</a></td></br>'; 
document.getElementById("togglemenu").addEventListener("click", changedisplay,false); 
+1

僅發佈相關代碼。閱讀規則。 – alt

+0

已更新代碼 – ECMAScript

+1

指向您的完整腳本的鏈接始終是適當的和讚賞的,*此外*相關的代碼片段應該在您的文章中。 –

回答

82

切勿使用.onclick(),或從userscript相似的屬性!(這也是poor practice in a regular web page)。

原因是userscripts在沙箱(「孤立的世界」)中運行,onclick在目標頁面範圍內運行,並且看不到腳本創建的任何函數。

始終使用addEventListener()Doc(或等效庫函數,如jQuery .on())。

因此,而不是像代碼:

something.outerHTML += '<input onclick="resetEmotes()" id="btnsave" ...>' 


你可以使用:

something.outerHTML += '<input id="btnsave" ...>' 

document.getElementById ("btnsave").addEventListener ("click", resetEmotes, false); 

對於循環,您不能數據傳遞給事件偵聽器一樣,見the doc。再加上你每次改變innerHTML這樣的話,你就會摧毀以前的事件監聽器!

不用重構你的代碼,你可以通過數據屬性傳遞數據。因此,使用這樣的代碼:

for (i = 0; i < EmoteURLLines.length; i++) { 
    if (checkIMG (EmoteURLLines[i])) { 
     localStorage.setItem ("nameEmotes", JSON.stringify (EmoteNameLines)); 
     localStorage.setItem ("urlEmotes", JSON.stringify (EmoteURLLines)); 
     localStorage.setItem ("usageEmotes", JSON.stringify (EmoteUsageLines)); 
     if (i == 0) { 
      console.log (resetSlot()); 
     } 
     emoteTab[2].innerHTML += '<span style="cursor:pointer;" id="' 
           + EmoteNameLines[i] 
           + '" data-usage="' + EmoteUsageLines[i] + '">' 
           + '<img src="' + EmoteURLLines[i] + '" /></span>' 
           ; 
    } else { 
     alert ("The maximum emote (" + EmoteNameLines[i] + ") size is (36x36)"); 
    } 
} 
//-- Only add events when innerHTML overwrites are done. 
var targetSpans = emoteTab[2].querySelectorAll ("span[data-usage]"); 
for (var J in targetSpans) { 
    targetSpans[J].addEventListener ("click", appendEmote, false); 
} 

哪裏appendEmote是這樣的:

​​


警告:

  • 您的代碼重用相同ID的幾個元素。不要這樣做,這是無效的。給定的ID應該每頁只出現一次。
  • 每次使用.outerHTML.innerHTML時,都會在受影響的節點上垃圾回收任何事件處理程序。如果您使用這種方法,請注意這一事實。
+1

我收到此錯誤:未捕獲TypeError:對象3沒有方法'addEventListener' – ECMAScript

+1

聽衆似乎並沒有爲我工作.. – ECMAScript

+0

你做錯了,那麼。鏈接到發出該錯誤的完整腳本,並鏈接到它所運行的目標頁面。 –

相關問題