Uncaught ReferenceError: функция не определена с помощью onclick
Я пытаюсь сделать userscript для веб-сайта, чтобы добавить пользовательские эмоции. Тем не менее, я получаю много ошибок.
вот функция:
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.");
}
}
The span тега!--5-- > вызывает эту функцию:
function appendEmote(em) {
shoutdata.value += em;
}
каждый раз, когда я нажимаю кнопку, которая имеет
1 ответ:
никогда не используйте
.onclick()
, или аналогичные атрибуты из пользовательского скрипта! (кроме плохая практика в обычной веб-странице).причина в том, что userscripts работают в песочнице ("изолированный мир"), и
onclick
работает в области целевой страницы и не может видеть никаких функций, создаваемых вашим скриптом.всегда использовать
addEventListener()
Doc (или эквивалентная библиотечная функция, например jQuery .on ()).поэтому вместо кода типа:
something.outerHTML += '<input onclick="resetEmotes()" id="btnsave" ...>'
Вы бы использовали:something.outerHTML += '<input id="btnsave" ...>' document.getElementById ("btnsave").addEventListener ("click", resetEmotes, false);
для цикла вы не можете передавать данные в прослушиватель событий, как это см. док. Плюс каждый раз, когда вы меняете
innerHTML
таким образом, вы уничтожаете предыдущих слушателей событий!без рефакторинга кода много, вы можете передавать данные с атрибутами данных. Так что используйте код это:
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); }
где appendEmote, как:
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; }
предупреждения:
- ваш код использует один и тот же идентификатор для нескольких элементов. Не делай этого, это недопустимо. Данный идентификатор должен встречаться только один раз на странице.
- каждый раз, когда вы используете
.outerHTML
или.innerHTML
, вы уничтожаете любые обработчики событий на затронутых узлах. Если вы используете этот метод остерегайтесь этого факта.