Nicht erfasster ReferenceError: Die Funktion wird nicht mit onclick definiert

84

Ich versuche, ein Benutzer-Skript für eine Website zu erstellen , um benutzerdefinierte Emotes hinzuzufügen. Ich habe jedoch viele Fehler bekommen.

Hier ist die Funktion:

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

Das spanTag onclickruft diese Funktion auf:

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

Jedes Mal, wenn ich auf eine Schaltfläche mit einem onclickAttribut klicke, wird folgende Fehlermeldung angezeigt:

Nicht erfasster ReferenceError: Funktion ist nicht definiert.

Jede Hilfe wäre dankbar.

Vielen Dank!

Aktualisieren

Ich habe versucht:

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

Aber ich habe einen undefinedFehler bekommen.

Hier ist das Skript .

Ich habe versucht, dies zu tun, um zu testen, ob Zuhörer funktionieren und sie nicht für mich:

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);
ECMAScript
quelle
1
Nur relevanten Code posten. Lese die Regeln.
Alt
1
Der Link zu Ihrem vollständigen Skript ist immer angemessen und wird geschätzt, zusätzlich zu den relevanten Codefragmenten, die in Ihrem Beitrag enthalten sein sollten.
Brock Adams

Antworten:

130

Verwenden Sie niemals .onclick()oder ähnliche Attribute aus einem Userscript! (Es ist auch eine schlechte Praxis auf einer normalen Webseite ).

Der Grund dafür ist, dass Benutzerskripte in einer Sandbox ("isolierte Welt") und onclickim Bereich der Zielseite ausgeführt werden und keine von Ihrem Skript erstellten Funktionen sehen können.

Verwenden Sie immer addEventListener()Doc (oder eine gleichwertige Bibliotheksfunktion wie jQuery .on () ).

Also anstelle von Code wie:

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


Sie würden verwenden:

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

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

Für die Schleife können Sie keine Daten an einen solchen Ereignis-Listener übergeben. Siehe Dokument . Und jedes Mal, wenn Sie sich so ändern innerHTML, zerstören Sie die vorherigen Ereignis-Listener!

Ohne Ihren Code stark umzugestalten, können Sie Daten mit Datenattributen übergeben. Verwenden Sie also folgenden Code:

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

Wo appendEmote ist wie:

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


WARNHINWEISE:

  • Ihr Code verwendet dieselbe ID für mehrere Elemente. Tu das nicht, es ist ungültig. Eine bestimmte ID sollte nur einmal pro Seite vorkommen.
  • Jedes Mal, wenn Sie .outerHTMLoder verwenden .innerHTML, werfen Sie Event-Handler auf den betroffenen Knoten in den Papierkorb. Wenn Sie diese Methode verwenden, achten Sie auf diese Tatsache.
Brock Adams
quelle
1
Ich erhalte diesen Fehler: Nicht gefangener Typfehler: Objekt 3 hat keine Methode 'addEventListener'
ECMAScript
Dann machst du es falsch. Verknüpfen Sie mit dem vollständigen Skript, das diesen Fehler verursacht hat, UND mit der Zielseite, auf der es ausgeführt wird.
Brock Adams
2
Ich habe Folgendes behoben: btnreset.onclick = function () {resetEmotes (); }; Vielen Dank!
ECMAScript
Ich bin froh, dass Sie es zum Laufen gebracht haben, aber diese Technik funktioniert nur unter bestimmten Bedingungen und ist nicht tragbar.
Brock Adams
Mein Code ist wirklich schlecht codiert, daher codiere ich das Ganze neu und verwende jQuery. Vielen Dank!
ECMAScript
3

Ich habe den Fehler erhalten (ich verwende Vue) und habe meinen onclick="someFunction()"auf umgestellt @click="someFunction"und jetzt funktionieren sie.

nbixler
quelle
Die Frage bezieht sich nicht auf Vue
Dave Manuel
-2

Wenn die Funktion bei Verwendung dieser Funktion in HTML nicht definiert ist, z. B. onclick = 'function ()', bedeutet dies, dass sich die Funktion in einem Rückruf befindet, in meinem Fall 'DOMContentLoaded'.

Vũ Đức Vĩ
quelle
1
Dies ist keine Antwort. Sie können es als Kommentar posten (indem Sie einen guten Ruf aufbauen). Bitte lesen Sie Wie schreibe ich eine gute Antwort?
EhsanT