web-dev-qa-db-fra.com

Uncaught ReferenceError: la fonction n'est pas définie avec onclick

J'essaie de faire un usercript pour un site Web afin d'ajouter des émotes personnalisées. Cependant, j'ai eu beaucoup d'erreurs.

Voici la fonction:

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

La balise spanonclick appelle cette fonction:

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

Chaque fois que je clique sur un bouton ayant un attribut onclick, j'obtiens cette erreur:

Uncaught ReferenceError: la fonction n'est pas définie.

Toute aide serait appréciée.

Je vous remercie!

Mise à jour

J'ai essayé d'utiliser:

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

Mais j'ai une erreur undefined.

Voici le script .

J'ai essayé de faire cela pour vérifier si les auditeurs travaillent et s'ils ne le font pas pour moi:

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

N'utilisez jamais .onclick(), ni d'attributs similaires à partir d'un script utilisateur! (c'est aussi mauvaise pratique dans une page Web classique ).

La raison en est que les scripts utilisateurs fonctionnent dans un sandbox ("monde isolé") et que onclick fonctionne dans la portée de la page cible et ne peut voir aucune fonction créée par votre script.

Toujours utiliser addEventListener()Doc (ou une fonction de bibliothèque équivalente, comme jQuery . on () ).

Donc au lieu de code comme:

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


Vous utiliseriez:

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

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

Pour la boucle, vous ne pouvez pas transmettre de données à un écouteur d'événement comme celui-ci See the doc . De plus, chaque fois que vous changez innerHTML comme ça, vous détruisez les écouteurs précédents!

Sans refactoriser votre code, vous pouvez transmettre des données avec des attributs de données. Utilisez donc un code comme celui-ci:

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

Où appendEmote est comme:

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


AVERTISSEMENTS:

  • Votre code réutilise le même identifiant pour plusieurs éléments. Ne fais pas ça, c'est invalide. Un identifiant donné ne doit apparaître qu'une fois par page.
  • Chaque fois que vous utilisez .outerHTML ou .innerHTML, vous supprimez tous les gestionnaires d'événements sur les nœuds concernés. Si vous utilisez cette méthode, méfiez-vous de ce fait.
106
Brock Adams

Je recevais l'erreur (j'utilise Vue) et j'ai changé ma onclick="someFunction()" en @click="someFunction" et ils fonctionnent maintenant.

0
nbixler