2013-06-29 18 views
51

Sto cercando di creare un userscript per un sito Web per aggiungere emote personalizzate. Tuttavia, ho ricevuto molti errori.Uncaught ReferenceError: la funzione non è definita con onclick

Qui è la funzione:

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

onclick chiamate del tag span questa funzione:

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

Ogni volta che si fa clic su un pulsante che ha un attributo onclick, ottengo questo errore:

Uncaught ReferenceError: function is not defined.

Qualsiasi aiuto sarebbe apprezzato.

Grazie!

Aggiornamento

Ho provato ad utilizzare:

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

ma ho ottenuto un errore undefined.

Ecco lo script.

Ho provato a fare questo per verificare se gli ascoltatori di lavoro e non lo fanno per me:

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

Solo codice pertinente. Leggi le regole. – alt

+0

Aggiornamento del codice – ECMAScript

+1

Il collegamento allo script completo è sempre appropriato e apprezzato * in aggiunta * ai frammenti di codice pertinenti che dovrebbero essere inclusi nel post. –

risposta

82

Non usare mai .onclick(), o attributi simili da un userscript! (È anche poor practice in a regular web page).

Il motivo è che gli usercripts operano in una sandbox ("mondo isolato") e onclick opera nell'obiettivo della pagina di destinazione e non può vedere alcuna funzione creata dallo script.

Utilizzare sempre addEventListener()Doc (o una funzione di libreria equivalente, come jQuery .on()).

Così, invece di codice come:

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


si userebbe:

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

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

per il ciclo, non è possibile passare i dati di un listener di eventi del genere Vedi the doc. Inoltre, ogni volta che cambi lo innerHTML in questo modo, distruggi i precedenti ascoltatori di eventi!

Senza il codice molto refactoring, è possibile passare i dati con gli attributi dei dati.Quindi, utilizzare il codice come questo:

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

Dove appendEmote è come:

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


AVVERTENZE:

  • Il codice riutilizza lo stesso ID per diversi elementi. Non farlo, non è valido. Un dato ID dovrebbe verificarsi solo una volta per pagina.
  • Ogni volta che si utilizza .outerHTML o .innerHTML, si cestino qualsiasi gestore di eventi sui nodi interessati. Se usi questo metodo, fai attenzione a questo fatto.
+1

Ho ricevuto questo errore: Uncaught TypeError: L'oggetto 3 non ha il metodo 'addEventListener' – ECMAScript

+1

Gli ascoltatori non sembrano funzionare per me .. – ECMAScript

+0

Stai sbagliando, allora. Link allo script completo che ha dato quell'errore, AND link alla pagina di destinazione su cui gira. –

Problemi correlati