2013-06-29 114 views
51

私はuserscriptにカスタムエモートを追加しようとしています。しかし、私は多くのエラーを受けてきました。ここでUncaught ReferenceError:関数がonclickで定義されていません

が関数である:

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: function is not defined.

ご協力いただければ幸いです。

ありがとうございました!

更新

私が使用してみました:

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エラーを得ました。

ここにはscriptがあります。

私は、リスナーが動作し、彼らは私のためにないかどうかをテストするためにこれをやってみました:

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

関連コードのみを入力してください。ルールを読んでください。 – alt

+0

コード – ECMAScript

+1

を更新しましたあなたの完全なスクリプトへのリンクは、あなたの投稿に含める必要がある関連するコードスニペットに加えて*常に*適切です。 –

答えて

82

userscriptから.onclick()、または同様の属性を使用しないでください!(これもpoor practice in a regular web pageです)。

なぜなら、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); 
Forループ

は、あなたがそれを参照してくださいのようなイベントリスナーにデータを渡すことはできませんthe doc。あなたがそのようにinnerHTMLを変更するたびに、以前のイベントリスナーを破壊します!

コードを多くリファクタリングしないと、データ属性でデータを渡すことができます。したがって、このようなコードを使用:appendEmoteは次のようである

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

どこ:

​​


警告:

  • あなたのコードでは、いくつかの要素に同じIDを再利用します。これをしないでください、それは無効です。与えられたIDはページごとに1回しか出現しません。
  • .outerHTMLまたは.innerHTMLを使用するたびに、影響を受けるノードですべてのイベントハンドラをゴミ箱に入れます。この方法を使用する場合、その事実に注意してください。
+1

このエラーが表示されます。未知の型エラー:オブジェクト3にメソッド 'addEventListener'がありません – ECMAScript

+1

リスナーが私のために機能していないようです.. – ECMAScript

+0

あなたは間違っています。そのエラーを出した完全なスクリプトにリンクし、それが実行されているターゲットページにリンクします。 –

関連する問題