未捕获的ReferenceError:函数未使用onclick定义 [英] Uncaught ReferenceError: function is not defined with onclick

查看:281
本文介绍了未捕获的ReferenceError:函数未使用onclick定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为网站制作一个 userscript 来添加自定义表情。但是,我遇到了很多错误。

I'm trying to make a userscript for a website to add custom emotes. However, I've been getting a lot of errors.

这是函数:

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的按钮属性,我收到此错误:

Every time I click a button that has an onclick attribute, I get this error:


未捕获的ReferenceError:函数未定义。

Uncaught ReferenceError: function is not defined.

任何帮助都将不胜感激。

Any help would be appreciated.

谢谢!

我尝试使用:

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 错误。

这是脚本

我试过这个来测试听众是否有效,而且他们不适合我:

I tried doing this to test if listeners work and they don't for me:

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


推荐答案

从不使用 .onclick(),或来自用户的类似属性!(它也是常规网页)。

Never use .onclick(), or similar attributes from a userscript! (It's also poor practice in a regular web page).

原因是用户脚本在沙箱中运行(孤立世界), onclick 在目标页面范围内运行,无法看到脚本创建的任何函数。

The reason is that userscripts operate in a sandbox ("isolated world"), and onclick operates in the target-page scope and cannot see any functions your script creates.

始终使用 addEventListener() Doc (或等效的库函数,如jQuery .on())。

所以代替以下代码:

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



您将使用:


You would use:

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

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






对于循环,您无法传递数据这样的事件监听器请参见文档。再加上每次更改 innerHTML 时,你会破坏以前的事件监听器!


For the loop, you can't pass data to an event listener like that See the doc. Plus every time you change innerHTML like that, you destroy the previous event listeners!

不重构你的代码,您可以使用数据属性传递数据。所以使用这样的代码:

Without refactoring your code much, you can pass data with data attributes. So use code like this:

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如下:

Where appendEmote is like:

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



  • 您的代码重复使用多个元素的相同ID。不要这样做,它是无效的。给定的ID每页只能出现一次。

  • 每次使用 .outerHTML .innerHTML ,您在受影响的节点上删除任何事件处理程序。如果您使用此方法,请注意这一事实。

  • Your code reuses the same id for several elements. Don't do this, it's invalid. A given ID should occur only once per page.
  • Every time you use .outerHTML or .innerHTML, you trash any event handlers on the affected nodes. If you use this method beware of that fact.

这篇关于未捕获的ReferenceError:函数未使用onclick定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆