Я пытаюсь создать пользовательский скрипт для веб-сайта, чтобы добавить собственные эмоции. Однако у меня было много ошибок.
Вот функция:
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.");
}
}
В span
теге onclick
вызывает эту функцию:
function appendEmote(em) {
shoutdata.value += em;
}
Каждый раз, когда я нажимаю кнопку с onclick
атрибутом, я получаю эту ошибку:
Uncaught ReferenceError: функция не определена.
Любая помощь будет оценена.
Спасибо!
Обновить
Я пробовал использовать:
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);
Но у меня undefined
ошибка.
Вот сценарий .
Я попытался сделать это, чтобы проверить, работают ли слушатели, а они нет для меня:
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);
javascript
onclick
userscripts
ECMAScript
источник
источник
Ответы:
Никогда не используйте
.onclick()
или аналогичные атрибуты из пользовательского скрипта! (Это также плохая практика на обычной веб-странице ).Причина в том, что пользовательские сценарии работают в изолированной программной среде («изолированном мире»),
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
, вы удаляете все обработчики событий на затронутых узлах. Если вы используете этот метод, остерегайтесь этого факта.источник
Я получал ошибку (я использую Vue), я переключился
onclick="someFunction()"
на,@click="someFunction"
и теперь они работают.источник
Убедитесь, что вы используете модуль Javascript или нет ?! при использовании модулей js6 ваши атрибуты событий html не будут работать. в этом случае вы должны перенести свою функцию из глобальной области в область видимости модуля. Просто добавьте это в свой файл javascript:
window.functionName= functionName;
пример:
<h1 onClick="functionName">some thing</h1>
источник
Я думаю, вы поместили функцию в $ (document) .ready ....... Функции всегда предоставляются в $ (document) .ready .......
источник
Я разрешил это в angular с
(click) = "someFuncionName()"
помощью файла .html для конкретного компонента.источник
Если функция не определена при использовании этой функции в html, например onclick = 'function ()', это означает, что функция находится в обратном вызове, в моем случае это 'DOMContentLoaded'.
источник