2013-06-29 22 views
51

Próbuję utworzyć userscript dla strony internetowej, aby dodać niestandardowe emotikony. Jednak dostaję wiele błędów.Niepowodzenie ReferenceError: funkcja nie jest zdefiniowana za pomocą onclick

Oto funkcja:

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."); 
    } 
} 

na span tagu onclick wywołania tej funkcji:

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

każdym razem, kiedy kliknij przycisk, który ma atrybut onclick, otrzymuję ten błąd:

Uncaught ReferenceError: function is not defined.

Każda pomoc zostanie doceniona.

Dziękujemy!

Aktualizacja

Próbowałem za pomocą:

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); 

Ale mam błąd undefined. To jest script.

Próbowałem w ten sposób, aby sprawdzić, czy słuchacze pracują i nie dla mnie:

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

Opublikuj odpowiedni tylko kod. Przeczytaj zasady. – alt

+0

Zaktualizowany kod – ECMAScript

+1

Link do pełnego skryptu jest zawsze odpowiedni i doceniany, * dodatkowo * do odpowiednich fragmentów kodu, które powinny znajdować się w Twoim poście. –

Odpowiedz

82

Nigdy nie używaj .onclick() lub podobne atrybuty z userscript! (Jest to również poor practice in a regular web page).

Powodem jest to, że userscripts działają w piaskownicy ("izolowany świat"), a onclick działa w zasięgu strony docelowej i nie widzi żadnych funkcji tworzonych przez skrypt.

Zawsze używaj addEventListener()Doc (lub równoważnej funkcji bibliotecznej, takiej jak jQuery .on()).

Więc zamiast kodu, takich jak:

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


użyłbyś:

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

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

Na pętli, nie można przekazać dane do detektora zdarzeń takiego Zobacz the doc. Dodatkowo za każdym razem, gdy zmieniasz innerHTML, niszczycie poprzednich słuchaczy!

Bez znacznej korekty kodu można przekazywać dane za pomocą atrybutów danych.Więc użyć kodu jak poniżej:

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); 
} 

Gdzie appendEmote jest jak:

function appendEmote (zEvent) { 
    //-- this and the parameter are special in event handlers. see the linked doc. 
    var emoteUsage = this.getAttribute ("data-usage"); 
    shoutdata.value += emoteUsage; 
} 


ostrzeżenia:

  • Kod ponownie wykorzystuje ten sam identyfikator dla kilku elementów. Nie rób tego, jest nieważny. Podany identyfikator powinien pojawić się tylko raz na stronę.
  • Za każdym razem, gdy używasz .outerHTML lub .innerHTML, usuwasz wszystkie programy do obsługi zdarzeń z zagrożonych węzłów. Jeśli użyjesz tej metody, strzeż tego faktu.
+1

Otrzymuję ten błąd: Uncaught TypeError: Obiekt 3 nie ma metody 'addEventListener' – ECMAScript

+1

Słuchacze nie wydają się pracować dla mnie .. – ECMAScript

+0

Robisz to źle, to. Link do pełnego skryptu, który spowodował ten błąd, i łącze do strony docelowej, na której działa. –

Powiązane problemy