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

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

新規登録して質問してみよう
ただいま回答率
85.49%
JavaScript

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

jQuery

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

HTML

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

Q&A

解決済

2回答

25420閲覧

【jQuery】changeイベントが何度も走るのを防ぎたい

k499778

総合スコア599

JavaScript

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

jQuery

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

HTML

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

0グッド

1クリップ

投稿2016/03/29 13:08

現在cakePHP3,PHP,jQuery,HTMLでアプリケーションを作っています。
画面にはリセットボタン、複数のチェックボックス、複数のセレクトボックスがあります。
リセットボタン押下ですべての項目が「選択なし」の状態になります。
そのリセットボタンの処理は共通のjavascriptで行われており、順番に状態が「選択なし」になっていきます。

その都度その都度で、項目を変更した際に走る「changeイベント」が走ってしまいます。

この「changeイベント」が何度も走ることを防ぐことはできますでしょうか?

どのタイミングでchangeイベントを走らせるようにするかはわからないのですが、
リセットボタンを押したときは、changeイベントの処理が一度だけ走るようにしたいのです。

そのようなことを実現できる方法がありましたら、教えていただきたいです。お願い致します。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ソースコードを示せる範囲で示さないと回答を得にくいと思います。

とりあえず、こういうケースで多いのが、イベントハンドラの中でイベントハンドラを登録してしまうものです。

javascript

1$(function() { 2 $('#myButton').change(function() { 3 console.log('year !'); 4 }); 5});

と書けば、$('#myButton')change イベントに対するハンドラは document.ready のタイミングで一度登録されるだけですが、

javascript

1$(window).on('orientationchange', function() { 2 $('#myButton').change(function() { 3 console.log('year !'); 4 }); 5});

とか書いちゃうと、スマホやタブレットを回転させるたびに change イベントのハンドラが追加されていってしまいます。

投稿2016/03/29 13:42

unau

総合スコア2468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unau

2016/03/29 13:44

ryls-nmm さんの回答へのコメントを拝見すると、ハンドラの多重登録の可能性が濃くなったと思います。「初期表示状態に戻す」処理の中に change イベントハンドラの追加が含まれていませんか。
ryls-nmm

2016/03/29 13:57

change の多重登録の確認なら、 change のリスナ内で、 console.log(event.target) としてイベントが起きた要素を表示してみると良いと思います 一回のリセットボタンで同じ要素が2回表示されていた場合は多重登録されています
k499778

2016/03/29 14:07

unauさん、回答ありがとうございます。 私も重々承知しています。示せるコードがあれば示したいのですが、今回は私用のものではないため範囲が限られてしまいます。お答えしづらいかとは思いますが、その中でお答えいただけると幸いです。 なるほど。多重登録の可能性ですね! 実際、項目を変更した際に処理をする仕様があるので、共通jsではなく、自分のコードの中でchangeイベントをonイベントを使って、定義しています。 このように ---- $('button').on('change', function() { alert('クリックされました'); }); ---- これがonイベントを使っているのが影響しているのでしょうか? 次のように書けば、多重登録がおさえられるのでしょうか? ---- $('button').change(function() { alert('クリックされました'); }); ----
k499778

2016/03/29 14:16

ryls-nmmさんも回答ありがとうございます。 >change のリスナ内で、 console.log(event.target) としてイベントが起きた要素を表示してみる というのは、changeイベントを使っている関数(リスナ)内に、console.log(event.target) という記述を追加して、その処理が実行された際に、デバッカーツールのコンソールに 要素が2回表示されてないか見てみる。という認識でよろしいでしょうか? デバッガーツールのコンソールにconsole.log(event.target) と打ち込むのではなくて。 ぜひ試してみます!
ryls-nmm

2016/03/29 14:23 編集

はい。上のコードみたところ event を受け取っていないのでそっちも忘れないで下さい 短いのでコード書いてしまうと、こういうことです $('button').on('change', function(event) { console.log(event.target) }) ところで、 button タグに change なんですか? select や input につけるものかと思っていましたけど
k499778

2016/03/29 14:33 編集

すいません。上のchangeのコードはあくまで例なので、実際は buttonタグではなくて、$('form')です。 eventについても了解です。ありがとうございます。
unau

2016/03/29 21:21 編集

用語に混乱が見られると思います。 input 要素などの値が変化したときに change イベントが起きます(イベントが発生します)。.on('change', FUNC) で change イベントが起きたときに起動されるハンドラを登録します。.change(FUNC) も同じように change イベントが起きたときに起動されるハンドラを登録します。 あと、コードの提示について、もちろん、公開できないケースが少なくないことも理解しておりますが、一部伏せる、置き換える、などしてできるだけ載せる努力をしていただけるとよいかな、と思います。どうしても見せられないならその理由を書くなど。回答する人への配慮をまったく考慮していない、回答者への敬意がまったく感じられない質問も散見されますので、そういったものと一線を画す文言があるとだいぶ心証が異なり、答えようという気にもなろうというものです。
unau

2016/03/29 14:51

form.change で気がつきましたが、イベントの伝搬にもご注意ください。 ハンドラ内で false を返さないと上位要素にイベントが伝搬します。 たとえば、input 要素が変更されたときに input 要素の change イベントハンドラ内で false を返さないと、form 要素でも change イベントが発生します。
k499778

2016/03/29 15:24

回答ありがとうございます。 コードの提示に関して、配慮のない質問と一線を画すため、できる限り努力していきます! 今回form要素にのみchangeイベントを設定し、input要素には設定していないので、 伝播は大丈夫だとは思いますが、そのような知識も頭に入れておきます。 ありがとうございます。 ちなみになんですが、このような書き方の認識であっていますでしょうか? ---- $('input').on('change', function(event) { console.log(event.target); return false; }); ----
unau

2016/03/29 21:25

はい、そういうことです。 イベントの伝搬をそこで終わりにする、あるいはデフォルトの動作をキャンセルする(たとえば a タグのクリックで独自処理を行ったあとに、href 属性で指定した先に飛ばさせない)のに用います。
k499778

2016/03/29 22:03

ありがとうございます!
guest

0

ベストアンサー

input type="reset" や、JavaScriptの処理では change イベントは発生しないとおもいます
(Chrome 以外は未確認)

たぶんリセットボタンの JavaScript の処理の中にイベントを発生させる処理があるのかとおもいます
jQuery だと trigger をそれぞれの input の変更のたびによんでいないでしょうか?

呼んでいるならその処理をやめて、リセットの処理の最後に、一度だけやりたい処理を呼び出せば良いと思います

投稿2016/03/29 13:17

ryls-nmm

総合スコア633

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k499778

2016/03/29 13:36

回答ありがとうございます。 はい。単純なリセット処理ではなく、 むしろリセットボタン押下時に初期表示状態に戻すといったような処理を行っています。 例えば、初期表示でDBの登録情報をフォームに反映させて、いろいろ変更した後にリセットボタンを押すと、初期表示の状態に戻る。といった具合です。 なのでjavascriptでいろいろ制御してはいます。 共通jsは変更しづらくコードが難解なため、まだ読み解けてはいませんが、 もしtriggerのような処理をしていてもそれをやめることは難しいような気がしています。
ryls-nmm

2016/03/29 13:52

trigger を呼んでしまっているなら難しいと思います また、共通jsで変更が他に影響があるなら簡単に trigger を消してしまうのもやめたほうがいいかもしれません 無理矢理ではありますが、発想を変えて change イベントで実行する関数では、フラグが立っていた時はなにもせず終了と if 文を追加します そして、リセットボタンを押した時の初期化処理より前にフラグをONにして、リセットボタンの初期化処理が終わったあとにOFFにする、ということをすればできなくはないかと思います リセットボタンの初期化処理の前と後に処理を入れるのは change にリスナを設定した順番で実行されるので、登録順を調整すればできます あまりオススメはできないですけど
k499778

2016/03/29 14:31

ryls-nmmさん、回答ありがとうございます。 なるほど。そういった発想もあるんですね!勉強になります。 少し理解できていない部分があるので質問させてください。 1点目 リセットボタン押下時にchangeイベントを一度発生させたいのですが、このやり方だとできるのでしょうか? 「リセットボタンの初期化処理後にOFFにし」ても、イベントは一度走るのかなと疑問に思いました。 2点目 >リセットボタンの初期化処理の前と後に処理を入れるのは change にリスナを設定した順番で実行されるので、登録順を調整すればできます ここが理解しきれていません。 「change にリスナを設定した順番」という所がとくにわかりません。 changeイベントの関数(下のもの)の書く位置を調整したら、発生位置を調整できるというようなことでしょうか? ---- $('button').on('change', function() { alert('クリックされました'); }); ----
ryls-nmm

2016/03/29 14:49

すみません コードがないのでわかりづらかったかもです リセットボタンを押した時に元に戻す処理をするので、共通jsにはこんな感じのコードがあるはずです --- $(/* リセットボタン */).on("click", function(event){ // リセット処理 }) --- また、リスナの関数が実行される順は登録した順番なので、 --- $(/* リセットボタン */).on("click", function(event){ console.log(1) }) $(/* リセットボタン */).on("click", function(event){ console.log(2) }) $(/* リセットボタン */).on("click", function(event){ console.log(3) }) --- と3回登録した場合は、 1, 2, 3 の順番で表示されます これらのことから、リセット処理をするリスナ登録の前に フラグONにするリスナをつけます そして、リセット処理をするリスナの登録よりあとに フラグOFFにするリスナをつけます これだけだと一度もリセット処理をするイベントが起きないので、フラグOFFにしたあとに trigger メソッドで一度 change に設定した関数を呼び出します
k499778

2016/03/29 15:17 編集

コードに関して失礼しました。 回答して頂きありがとうございます。 例えばこのような感じでしょうか? ---- $('form').on("change", function(event){ if(flg){ return false; } console.log(1); }); var flg ; $(/* リセットボタン */).on("click", function(event){ flg =true; // リセット処理 flg =false; $('form').trigger("change"); }) ---- コードの書き方にミスがあるかもしれません。すいません。
ryls-nmm

2016/03/29 16:11

ちょっと思っていたのとは違いますが、それで大丈夫だと思います 「// リセット処理」のところで trigger が行われていても一回しか実行されないはずです これで二回起きていたら もう一方の回答のほうで出ている多重登録でしょう (多重登録だとひとつの trigger で2回実行されてしまうので)
unau

2016/03/29 21:48

余計なことかもしれませんが、フラグは $('form').data('initializing') や $.data('form_initializing') などに格納してもいいかな、と思いました。 $('form').on('change', function(event) { if ($.data('form_initializing')) return false; console.log(1); }); $(/* リセットボタン */).on('change', function(event) { $.data('form_initializing') = true; // リセット処理 $.data('form_initializing') = false; ... });
k499778

2016/03/29 22:06

お二方とも親切に丁寧にお答え頂きありがとうございます。今日勝負してきます! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問