Error de referencia no detectado: la función no está definida con onclick

Resuelto ECMAScript asked hace 11 años • 8 respuestas

Estoy intentando crear un script de usuario para un sitio web para agregar emoticones personalizados. Sin embargo, he recibido muchos errores.

Aquí está la función:

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 spanetiqueta onclickllama a esta función:

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

Cada vez que hago clic en un botón que tiene un onclickatributo, aparece este error:

Error de referencia no detectado: la función no está definida.

Actualizar

Intenté usar:

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

Pero recibí un undefinederror.

Aquí está el guión .

Intenté hacer esto para comprobar si los oyentes funcionan y no para mí:

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 avatar Jun 29 '13 15:06 ECMAScript
Aceptado

¡Nunca utilices .onclick()atributos similares de un script de usuario! (También es una mala práctica en una página web normal ).

La razón es que los scripts de usuario operan en una zona de pruebas ("mundo aislado"), onclickoperan en el alcance de la página de destino y no pueden ver ninguna función que cree su script.

Utilice siempre addEventListener()Doc (o una función de biblioteca equivalente, como jQuery .on() ).

Entonces, en lugar de código como:

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


Usarías:

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

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

Para el bucle, no puede pasar datos a un detector de eventos como ese. Consulte el documento . Además, cada vez que cambias innerHTMLde esa manera, ¡destruyes a los oyentes del evento anterior!

Sin refactorizar mucho su código, puede pasar datos con atributos de datos. Entonces usa un código como este:

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

Donde appendEmote es como:

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


ADVERTENCIAS:

  • Su código reutiliza la misma identificación para varios elementos. No hagas esto, no es válido. Una identificación determinada debe aparecer solo una vez por página.
  • Cada vez que usas .outerHTMLo .innerHTML, eliminas cualquier controlador de eventos en los nodos afectados. Si utiliza este método, tenga cuidado con ese hecho.
Brock Adams avatar Jun 29 '2013 09:06 Brock Adams

¿Asegúrate de estar utilizando el módulo Javascript o no? Si usa módulos js6, sus atributos de eventos html no funcionarán. en ese caso, debe llevar su función del alcance global al alcance del módulo. Simplemente agregue esto a su archivo javascript: window.functionName= functionName;

ejemplo:

<h1 onClick="functionName">some thing</h1>
Mohammad reza hedayat nia avatar Nov 23 '2020 13:11 Mohammad reza hedayat nia