Error de referencia no detectado: la función no está definida con onclick
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 span
etiqueta onclick
llama a esta función:
function appendEmote(em) {
shoutdata.value += em;
}
Cada vez que hago clic en un botón que tiene un onclick
atributo, 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 undefined
error.
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&popup=true&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);
¡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"), onclick
operan 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 innerHTML
de 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
.outerHTML
o.innerHTML
, eliminas cualquier controlador de eventos en los nodos afectados. Si utiliza este método, tenga cuidado con ese hecho.
¿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>