質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • JavaScript

    17025questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    9290questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • jQuery

    6930questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

追加した要素にすでにあるイベントハンドラを再登録したい2

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,346

k499778

score 501

前回の投稿の続きです。
追加した要素にすでにあるイベントの処理を再設定したい

前回の投稿で追加した要素に対して、イベントハンドラを再登録する方法を学べました。

個人的に関数を宣言しておき、それをonイベントで再登録する方法が一番シンプルでいいなと思ったのですが。

引数がある場合はどのような書き方になるのでしょうか?

例えばこのような場合です。

function handleClick (_this) {
   console.log(_this.val());
}

このような書き方でいけるかと試したのですが、handleClick is not defined のようなエラーが出て実行できませんでした。

// #testBtn をDOMツリーに挿入する

jQuery('#testBtn').on('click', handleClick(this));

書き方が間違っているでしょうか?
それとも書き方はあっているけど他の理由でエラーが出ているのでしょうか?

もしわかる方がいらっしゃったら教えていいただければと思います。


追記

一例ですが、今回のパターンで言うと
<input type="file">を使って画像を表示したいのときです。

以下サイトの $('.fileInput').change(function(){の中を関数にしたいのです。
FileAPIを使った画像表示

というのも<input type="file">の値を消すのにIEの古いバージョンだと一度このコードを消してしまって
もう一度生成しなければいけないからです。
アップロード時に選択したファイルをクリア
そのとき再度changeイベントを登録するのに、いちいちこの長ったらしいコードを書かずに済むように関数化しておきたいというところです。

$('.fileInput').change(function(){
  displayImage(this);
}



function displayImage(_this) {
    // 1. 選択されたファイルがない場合は何もせずにreturn
    if (!_this.files.length) {
        return;
    }

    var file = _this.files[0], // 2. files配列にファイルが入っています
        $_img = $(_this).siblings('img'), // 3. jQueryのsiblingsメソッドで兄弟のimgを取得
        fileReader = new FileReader(); // 4. ファイルを読み込むFileReaderオブジェクト

    // 5. 読み込みが完了した際のイベントハンドラ。imgのsrcにデータをセット
    fileReader.onload = function(event) {
        // 読み込んだデータをimgに設定
        $_img.attr('src', event.target.result);
    };

    // 6. 画像読み込み
    fileReader.readAsDataURL(file);
}


// displayImage(this)を再登録したい
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2016/04/26 10:40

    引数の使い方、準備の仕方、構造(何が入っているものかなど)を具体的に追記いただけませんか?

    キャンセル

  • k499778

    2016/04/27 22:28

    追記いたしました

    キャンセル

  • kei344

    2016/04/27 22:41

    「引数がある場合」の部分のコードが追加された部分にも見当たりませんが、具体的なコードを質問文に追加いただけませんか?

    キャンセル

  • k499778

    2016/04/27 22:49

    再度追記いたしました

    キャンセル

回答 3

checkベストアンサー

+2

イベントハンドラー登録を

jQuery('#testBtn').on('click', handleClick);

ハンドラーを

function handleClick() {
  console.log($(this).val());
?

に修正すると動くのでは。
this は引数として渡す必要はありません。this に関する説明はこちらのサイトでの説明が解りやすいでしょうか。

ご参考になれば。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/26 00:00

    回答有り難うございます。

    それって引数thisは受け取れているのでしょうか?

    キャンセル

  • 2016/04/26 00:04

    あ、そうですね。ハンドラー側も少し修正が必要ですね。回答を修正します。

    キャンセル

  • 2016/04/26 07:03

    返答ありがとうございます。

    今回のthisの扱い方に関してはあくまで例で、実際引数にthisを渡さないといけないケースがよく出てくるんです。
    なので引数にthisを与えたまま、再登録する際も呼べるようにしたいのです。

    そのようにする方法はないのでしょうか?

    キャンセル

  • 2016/04/26 07:35

    ハンドラー関数の引数はjQuery.Eventオブジェクトと決まっていて変更できません。ただし、このイベントオブジェクト内にはクリックイベントの発生元エレメントなどの情報(event.targetプロパティ)が含まれているので、thisを使わなくてもイベント発生元を知ることは可能です。

    また、このイベントオブジェクトをプログラムコードで明示的に作成し、任意のDOMエレメントに対してイベント発行する事は可能なので、thisの引き渡しの問題を解決できるかもしれません。

    thisを引数として渡す必要が出てしまうケースというのがちょっと想像できないのですが、具体的に一つ例を挙げることは可能でしょうか?

    キャンセル

  • 2016/04/28 00:06

    「追記」していただいた <input type='file'> を作り直すケースについて。

    jQuery on() や click()、change() 等によるイベントハンドラ登録機能は動的に作成されたDOM要素にイベントハンドラを登録することができません。

    このため、clickやmouseoverなどのマウスイベントでは、イベント登録対象を静的に宣言された親要素(親DIVなど)とし、動的に作成された子要素にイベントをフォワードする機能が用意されています。

    > $('#parent_div').on('click','.child-element',function() { /* this が子要素を参照した状態で呼び出される */});

    ただ残念ながらこの方法は動的に作成される子要素にフォワードしたいイベント種別が 'change' の場合には使えません(親要素であるDIVが 'change' イベントを登録できないため)

    この場合、jQuery を利用せず、素のHTML DOMを使う必要があります。例えば・・・


    var f = document.createElement('input');

    f.setAttribute('type', 'file');

    f.addEventListener('change', displayImage);

    document.body.appendChild(f);


    このようなコードになると思われます。
    ご参考になれば。

    キャンセル

  • 2016/04/28 22:59 編集

    回答ありがとうございます。

    具体的なコードをあげてくださり、感謝いたします。
    jQueryでは厳しいということでJavaScriptのやり方を教えていただきましたが、
    これは引数thisを含んでいるのでしょうか?

    キャンセル

  • 2016/04/29 00:15

    thisではなく、event.targetプロパティを使うのですね

    キャンセル

+1

jQuery('#testBtn').on('click', handleClick(this));


とありますが、handleClick は関数オブジェクトですが、handleClick(this) は「handleClick という関数に this を実引数として渡して実行」した結果のもの、になります。
イベントハンドラとして(より一般的にはコールバック関数として)渡すのは関数オブジェクトでなければなりません。

また、コールバックとして登録する関数の「型」すなわち、どのような引数をとるか、は、コールバックを呼び出す側が規定しています。jQuery.on() の場合、コールバック関数は第一引数に eventObject を渡して実行されます。
次のリファレンスなどを参照してください。
.on() - Js STUDIO

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/26 07:26 編集

    回答ありがとうございます。
    今回の場合、関数オブジェクトではなく、実行した結果のものが渡されているため、
    うまく動作しないとわかりました。

    ではこのようなパターンの場合、どのようにしてonイベントの引数に渡してあげればいいかを知るため、提示してくださったリファレンスも見たのですが、やはりやり方がわかりません。

    引数this,あるいはthisでなくとも引数がある関数をonで扱うのはどうするのでしょうか?
    できないのでしょうか?再度関数定義していた処理の内容を全文書かないといけないのでしょうか?


    もしお時間ございましたら教えて頂けると大変ありがたいです。

    キャンセル

  • 2016/04/26 18:44

    k49978 さんが、自分で、コールバック関数を引数に取るような関数を定義するとしましょう。
    たとえば、setup() というメソッドにある整数とコールバック関数を与えてセットアップしたうえで exec() というメソッドを呼ぶと、1 から与えられた整数まで順に出力する、というオブジェクトを作るとします。ただし、3 の倍数と 3 がつく整数のときには、そのまま出力するのではなく、登録されているコールバック関数にその整数を渡して戻ってきた値を出力する、とします。
    具体的なコードは次のようになります。

    var three = {
    setup: function(limit, func) {
    this.limit = limit;
    this.func = func;
    return this;
    },
    exec: function() {
    for (var i = 1; i <= this.limit; i++) {
    console.log( (i % 3 == 0 || ('x' + i).indexOf('3') > 0) ?
    this.func(i) : i );
    }
    return this;
    }
    };

    使い方は、

    three.setup(15, function(i) { return '[' + i + ']'; }).exec();

    のようになります。

    で、k499778 さんがこの setup() 関数に指定するコールバック関数の仕様を説明する立場だったら、どのように説明するか、ということを考えてみてください。
    「コールバック関数は、第一引数に整数をとり、文字列を返す関数にしてください」というような説明になるかと思います。自分で作った exec() 関数の中でコールバック関数に何を引数に呼び出し、その戻り値をどのように使うかは決まっているわけですから、ユーザが自由に引数を指定したりできない、ということがおわかりいただけるでしょうか。
    jQuery の .on() のリファレンスを読むときにも、そういう観点から読むといいと思います。

    とか書きましたが、k499778 さんがイベントハンドラに渡したいと思っている this、すなわち、イベントが発生した DOM 要素は、明示的にイベントハンドラに渡す必要はありません。イベントハンドラ内の this がイベントの発生した DOM 要素にバインドされてイベントハンドラが起動されるからです。
    tkanda さんが回答されているのはそういうことです。this を渡さなくても、イベントハンドラ内の this がその DOM 要素になっている、ということです。

    あと、これは余談になりますが、同じような動作をする関数を複数回、コールバック関数として登録したい、というような場合、関数を返す関数を作ることで、「再度関数定義していた処理の内容を全文書かな」くても済むようになります。が、完全に余談です。今回は使う必要はまったくありません。まったくありませんが、例だけ示しておきます。

    function mkfunc(face) {
    return function(i) {
    return face + (function(n, i, r) {
    for (; i < n; i++) { r += '-'; }
    return r + '○';
    })(i, 0, '') + ' !!!';
    };
    }

    three
    .setup(10, mkfunc('(T_T)'))
    .exec()
    .setup(40, mkfunc('(・д・)'))
    .exec();

    キャンセル

  • 2016/04/28 23:00

    回答ありがとうございます。
    返答が遅くなっていることをお詫びします。

    内容がみなさん深く濃いのでその理解と派生した勉強に時間がかかっているため
    このような結果になっています。

    皆さん回答を一度自分の中で落とし込み、もう一度勉強しなおしてまたわからないことがあれば質問したいと思います。

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

    キャンセル

+1

イベントハンドラ関数にオブジェクトを渡す方法はいくつかありますが、jQuery を使用しているなら event.data を使うのが良いと思います。

Re: k499778 さん

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/28 23:00

    回答ありがとうございます。
    返答が遅くなっていることをお詫びします。

    内容がみなさん深く濃いのでその理解と派生した勉強に時間がかかっているため
    このような結果になっています。

    皆さん回答を一度自分の中で落とし込み、もう一度勉強しなおしてまたわからないことがあれば質問したいと思います。

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

    キャンセル

関連した質問

同じタグがついた質問を見る

  • JavaScript

    17025questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    9290questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • jQuery

    6930questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。