web-dev-qa-db-ja.com

onclickイベント内で呼び出されない関数

ライトボックスでプレーヤーを開くために、すべてのyoutubeリンクの最後にHTMLを追加します。これはこれまでの私のコードです:

_$(document).ready(function() {
  var valid_url = new RegExp('youtube\.com\/.*v=([a-zA-Z0-9_-]+)');
  var image_data = 'base64 encoded image';

  init();

  function init() {
    $('a').each(function() {
      if (valid_url.test($(this).attr('href'))) {
        $(this).after( ' <img src="' + image_data + '" onclick="open_litebox(\'hi\');" />' );
      }
    });
  }

  function open_litebox(param) {
    alert(param);
  }
});
_

次のように、youtubeリンクの後にHTMLを挿入するところまで機能します。

_<img src="base 64 data" onclick="open_litebox('hi')">
_

しかし、これをクリックしても、open_litebox()関数は呼び出されません。エラーコンソールを見ると、_open_litebox is not defined_というエラーが表示されますが、定義済みです。

ここで何が間違っているのかについて私はかなり無知です、誰かが私に手を貸してもらえますか?

ありがとう。

29
Wen

これは、jQueryを初めて使用するときの一般的な問題です。ここでの問題は、jQueryスコープ内で関数を定義したことです。つまり、通常の関数のように呼び出すだけではアクセスできません。あなたの問題の解決策は、あなたが書いた匿名レディ関数の外に関数定義を移動することです:

$(document).ready(function() {

    // do your stuff here

});

// define your functions here 
function my_func() {

}

ああ、私はあなたが定義した変数に対して同じことをすることを提案します。関数で行ったのと同じ問題が発生するため、準備ができた関数の外にも移動します。

47
Simon H

_open_litebox_関数は別の関数のスコープ内にあるため、グローバルに表示されません。あなたがやっていることの代わりに、.click()を使ってみてください:

これらの線に沿って何か:

_$(this).after( ' <img src="' + image_data + '" id='abc' />' );
$('#abc').click(open_litebox);
_

この方法を使用してリンクごとに個別のIDを生成する必要があるため、別の方法として、_<img>_タグのそれぞれに既知のclass属性を持たせ、$('.abc')(クラスがabcの場合)$('#abc')ではなく、1ステップで(つまり、$('a').eachの後に別の呼び出しとして)それを行います。

10
icyrock.com

他の答えは、_my_func_宣言を$(document).ready()の外に移動することで問題を解決できるという点で正しいですが、jQueryとは特に関係ないので、理由を明確にしたいと思います。

$(document).ready()は、ブラウザがドキュメントの準備ができたことを通知するときに実行するコールバックとして匿名関数を渡すイベントハンドラです。

コールバック関数内で_my_func_を定義したため、グローバルスコープからは見えないため、ページのonclick要素のimgプロパティから呼び出すことはできません。

JavaScriptでは、スコープは関数レベルです。関数内にないものはすべてグローバルスコープにまとめられます。

10
Rob Sobers

理由は、open_litebox()document.ready関数内で宣言されているため、グローバルスコープからアクセスできないためです。

関数をdocument.readyの外に移動するか、jQuery(関数を直接参照する)を使用してonclickハンドラーをアタッチするようにコードを変更できます。

var link = $(' <img src="' + image_data + '" />' ).click(function () {
   open_litebox('hi');
});
$(this).after(link);
2
David Tang

クリックアクションを割り当てるには、はるかに洗練されたjQueryの方法があります。

function init() {
    $('a').each(function() {
        if(valid_url.test($(this).attr('href'))){
            $(this).click( function() { open_litebox('hi'); });
        }
    });
}

これにより、他の回答で説明されているスコープの問題が解決されます。パラメーターを指定してopen_litebox()を呼び出す必要がある場合は、私と同じように匿名関数でラップします。そうしないと、関数が呼び出され、戻り値がクリックアクションに渡されます。それ以外の場合、渡すパラメーターがない場合、割り当てはより簡単です。

$(this).click( open_litebox );
0
Surreal Dreams