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

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

ただいまの
回答率

90.11%

ページを表示した後にイベントを発火したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 396

msx2

score 161

入力フォームを作成しました。

radioボタンにjQueryを使ってイベントを登録し
ページを読み込んだ後に動かそうとしています。

<html lang="ja">
    <head>
        <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    </head>
<body>
    <input type="radio" name="mail" value="1" checked>メール1<br>
    <input type="radio" name="mail" value="2">メール2
    <script>
    $(function(){
        $('input[name=mail]').on('change',function(){
            //途中でイベントを登録
            alert('イベント実行');
        });
    });
    </script>
    <!--
        その後あれこれとHTMLを記述して
        ~
        ~
        ~
    -->
    <script>
        //最後にイベントを発火させようとしている
        $(window).on('load',function(){
            alert('test');
            $('input[name=mail]:checked').change();
        });
    </script>
</body>
</html>

このやり方だとradioボタンのイベントはどうにも動いてくれません。
ちなみにalert('test')は表示されるのでコードは動いていますしエラーにもなっていません。

悩んだ末にイベントを登録した直後だと動くことがわかりました。

<html lang="ja">
    <head>
        <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    </head>
<body>
    <input type="radio" name="mail" value="1" checked>メール1<br>
    <input type="radio" name="mail" value="2">メール2
    <script>
    $(function(){
        $('input[name=mail]').on('change',function(){
            //途中でイベントを登録
            alert('イベント実行');
        });
        //ここだと動く
        $('input[name=mail]:checked').change();
    });
    </script>
</body>
</html>

質問しようと試しているうちに解決してしまったのですが
最初の書き方だとなぜイベントが動かないのかわかりません。

同じ$(function)内に書かないとイベントが発火しないものでしょうか?

jqueryのバージョンはLaravelに同梱されていた3.2.1です。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • think49

    2018/08/18 18:56

    動くコードを質問文に載せて下さい

    キャンセル

  • msx2

    2018/08/18 20:39

    コードを書く場所による違いを質問したいので、記述場所を示すのが目的のコードが必ずしも動く必要はないような気がします。 ありがたいことに拙い質問でも私の求める回答が得られ疑問を解消することができました。 ただteratailの質問と回答は自分だけのためではなく、同じような問題に直面した人たちにとって有用なコンテンツになると考えますので、そういう意味で提示のコードが不適切であれば解決後であっても修正するのがサイトへの貢献ですね。今はパソコンが使えないので週明けにでも確認してみます。

    キャンセル

  • think49

    2018/08/18 21:22

    検証しましたが、x_x さんが指摘された「提示コードではどちらにしてもcheckedがなくて動かないはずなので」が正しいようにしか思えません。

    キャンセル

回答 2

checkベストアンサー

+1

簡潔に述べると、jQuery関数でラップした処理とそうでない処理の実行タイミングは異なるんです。
以下、検証コード。

<input type="radio" name="mail" value="1" checked >メール1
<input type="radio" name="mail" value="2">メール2
<script>
$(function(){
    console.log('40')
    $('input[name=mail]').on('change',function(){
        //途中でイベントを登録して
        console.log('100');

    });
    console.log('50')
//    $( function(){ $('input[name=mail]:checked').change(); });
});
</script>
~
~
~
//最後にイベントを発火させようとしている
<script>
      console.log('10');
//    $( function(){ $('input[name=mail]:checked').change(); });
    $(window).on('load',function(){
            console.log('20');
                $( function(){ console.log('10010'); $('input[name=mail]:checked').change(); });
    });
</script>

質問文の「うまくいかないコード」に若干の修正を加えています。
一番大きな違いは、イベントを発火させるコードをjQuery関数 $() でラップしていることです。

各処理の前後でコンソールに数字が出力されます。出力順を追ってみてください。
上側のイベント登録処理はonloadの処理が終わった後に実行されています。
(logは10,20,10010,40,50の順)
なので、onload時にイベント発火処理を書いても何も起こらないのです。イベント登録処理前にすでに発火しちゃってるから。
で、このイベント発火処理を$()でラップすると、ラップしたブロックがイベント登録処理の後に実行されていることがわかります。
(logは10,20,40,50,10010,100)

jquery内の詳しい挙動はさすがにわからないのですが、イベント発生順を内部でよしなに整理してくれているのかもしれません。そのあたりは有識者求ム。

なお、イベント登録部分とイベント発火部分の記載順を逆にしても、期待通りに動きます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/08/18 12:52

    ご回答ありがとうございます!
    なんと、そういう事でしたか。イメージ的には上から順番にコードが実行されて最後にonloadのコードが実行されているものだとばかり…

    検証いただいた感じだとラップされてないコードが動いてからラップされたコードが上から順に実行されているっぽいですねー。(必ずしもそうとは限りませんけど)

    そういう挙動だとわかれば書き方を変えればいいだけなので修正できそうです!
    また検証のやり方も分かりましたので自力で解決できることが増えそうです。
    わざわざ検証までしていただいて本当にありがとうございました!!

    キャンセル

0

 質問文のコード

悩んだ末にイベントを登録した直後だと動くことがわかりました。

いいえ。動きません。

 checked 属性

動かない理由は$('input[name=mail]:checked')にマッチする要素ノードが存在しないからです。
checked属性を付与すれば、期待通りに動きます。

提示のコードは省略した上に投稿にあたって変更もしているので間違ってるかもしれません。質問の趣旨としては上と下のコードで記述場所によって動作が異なるのは何故か?というところで、セレクタの書き方がわからなくて困っているのではありません。

「セレクタが正しい」と主張するのでしたら、因果関係を正しく認識して下さい。
セレクタが正しいと確信できるのは、「正しいセレクタ」に対応する「正しいHTML」を理解している場合に限ります。
この結果を見る限りですと、正しく理解しているようには読めません。

  • $()
  • .on('change')
  • .on('load')
  • .change()

これらがどこまで期待通りに動き、どこから期待通りに動作していない(理解しない動きをする)か、を正しく切り分けできていないのが原因です。

 jQuery()

Re: msx2 さん

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/08/18 22:02

    ご回答ありがとうございます。
    わざわざ検証までしていただきまして感謝します。

    なるほど、私の説明が足りていないことがよく分かりました。コードの目的や前提などをちゃんと書かず親切な人の時間を無駄に奪ってしまったことを深くお詫び申し上げます。

    このフォームはPHPのテンプレート用で、POST送信される前提で書きました。PHPで値を設定するのですが、そういう部分をすっぱり省略してしまったのが最大の過ちです。

    今回の質問だとcheckedをどちらかに入れておくのが適当ですね。後ほど訂正しておきます。

    この度は大変お世話になりました。質問する側としても質問のスキルを向上すべく精進します。

    キャンセル

  • 2018/08/18 22:24

    JavaScriptからみれば出力されたHTMLが全てなので、PHPはどうでもいいのですが…。
    一番の問題は「投稿したコードだけで現象が再現可能な事を確認しなかったこと」と考えます。

    キャンセル

  • 2018/08/20 11:18

    投稿したコードを再現可能なものに修正しました。
    残念ながらchecked属性を付与するだけでは期待した動きにはなりませんでしたが…
    一生懸命やっていただきましてありがとうございます。

    キャンセル

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

  • ただいまの回答率 90.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる