onでデリゲートするときのエラー
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ jQuery
◆ $("body").on("click", "p", undefined);になると謎のエラー
原因のコードの場所がわからないので起こさないように気をつける
◆ $("body").on("click", "p", undefined);になると謎のエラー
原因のコードの場所がわからないので起こさないように気をつける
戦いに勝つためには敵を知らなくてはいけない
ということで今回はjQueryについてです
まずデリゲートですが最初 このページの中に説明書いていたのですが 本題並に長くなったので別ページ行きになりました
デリゲート?なにそれおいしいの? とか デリケート?それって私の事? とか思った人は先にこちらのページをご覧ください
jQueryではイベントリスナーつけるのをonでできます
色々ありましたが今はonでつけておくのが書くのも楽ですし全部onでいいんじゃないかと思います
onでは通常のイベントリスナーつけるのとデリゲート両方が可能です
2つ目はhandler(イベントが起きた時に実行する関数)なしでもいいのでどうするんだ?と思いましたが 2つ目の形にするときは events にkeyがイベント名でvalueがhandlerのオブジェクトを渡すことになるようです
具体的なよく使う使い方は
デリゲート版は
onの2つ目の引数にセレクタが来てます
では ここからがメインなコンテンツです
undefinedなんて書かないよ って思うと思いますが私だって書きたくて書いたんじゃないんです
(存在しないプロパティにアクセスするとundefinedが返ってきます)
これは普通のJavaScriptと同じです
エラーも起きないのでバグを見つけづらいですが クリックしたときの設定した動作が起きていないので場所がある程度想像つきます
こんなのです
自分の書いたコードのどこかという情報が全くありません
イベントリスナー自体の登録は正常に終わっていて 自分のコードにはエラーがないのでイベントが起きてjQueryが設定した関数を呼び出す時に関数じゃなくてエラーが起きているから仕様がないことではあります
せめて handlerがないなら登録完了させずにエラーを出すようにしてほしいです
シンプルなものならクリックした場所から このリスナー設定がおかしいって想像できるかもしれませんが ページ全体のinputボタンのクリックを監視しようとして bodyにonを使ってデリゲートありなリスナー設定をするとリスナーはbodyについているので画面中のどこをクリックしてもエラーが発生することになります
こうなるとどこがエラーかわからなくてすごく困ることになります
一応サンプルページ
このエラーを知っていれば 全部のリスナーからundefinedになってるところを探すこともできますが知らない人は原因が全然わからずずっと悩みそうですよね
このエラーがこの問題だけならググればなんとかなりそうですが エラーメッセージみたところ 他の原因でも起きそうな気もします
安全のためにはonのときは変数つかわず 関数リテラルを使うというのもありなのかもしれません
不便にはなりますが strictモードみたいなバグ減らすために機能を制限するって考え方もありますしね
ということで今回はjQueryについてです
まずデリゲートですが最初 このページの中に説明書いていたのですが 本題並に長くなったので別ページ行きになりました
デリゲート?なにそれおいしいの? とか デリケート?それって私の事? とか思った人は先にこちらのページをご覧ください
jQueryではイベントリスナーつけるのをonでできます
色々ありましたが今はonでつけておくのが書くのも楽ですし全部onでいいんじゃないかと思います
onでは通常のイベントリスナーつけるのとデリゲート両方が可能です
onの使い方
onの使い方ですがリファレンスだと.on(events[,selector][,data],handler)
.on(events[,selector][,data])
となっています2つ目はhandler(イベントが起きた時に実行する関数)なしでもいいのでどうするんだ?と思いましたが 2つ目の形にするときは events にkeyがイベント名でvalueがhandlerのオブジェクトを渡すことになるようです
具体的なよく使う使い方は
$("span.button").on("click", function(eve){/* ... */});
みたいな形ですねデリゲート版は
$("ul#button-li").on("click", "li", function(eve){/* ... */});
になりますonの2つ目の引数にセレクタが来てます
では ここからがメインなコンテンツです
handlerがundefined
functionが来るべきところにundefinedが来た場合の動作ですundefinedなんて書かないよ って思うと思いますが私だって書きたくて書いたんじゃないんです
$("body").on("click", 'input[type="button"]', eves.input_button_click);
にするところが$("body").on("click", 'input[type="button"]', eves.input_click);
になってたりで 知らず知らずにundefinedを入れてしまってたんです(存在しないプロパティにアクセスするとundefinedが返ってきます)
デリゲートしないとき
何も起きませんこれは普通のJavaScriptと同じです
エラーも起きないのでバグを見つけづらいですが クリックしたときの設定した動作が起きていないので場所がある程度想像つきます
デリゲートするとき
エラーが起きます しかもjQuery側のこんなのです
TypeError: ((m.event.special[e.origType] || (intermediate value)).handle || e.handler).apply is not a function jquery.min.js:3 m.event.dispatch @ jquery.min.js:3 m.event.add.r.handle @ jquery.min.js:3どこのエラーかが全くわからないです
自分の書いたコードのどこかという情報が全くありません
イベントリスナー自体の登録は正常に終わっていて 自分のコードにはエラーがないのでイベントが起きてjQueryが設定した関数を呼び出す時に関数じゃなくてエラーが起きているから仕様がないことではあります
せめて handlerがないなら登録完了させずにエラーを出すようにしてほしいです
シンプルなものならクリックした場所から このリスナー設定がおかしいって想像できるかもしれませんが ページ全体のinputボタンのクリックを監視しようとして bodyにonを使ってデリゲートありなリスナー設定をするとリスナーはbodyについているので画面中のどこをクリックしてもエラーが発生することになります
こうなるとどこがエラーかわからなくてすごく困ることになります
一応サンプルページ
結論
やっぱりjQueryはダメ!このエラーを知っていれば 全部のリスナーからundefinedになってるところを探すこともできますが知らない人は原因が全然わからずずっと悩みそうですよね
このエラーがこの問題だけならググればなんとかなりそうですが エラーメッセージみたところ 他の原因でも起きそうな気もします
安全のためにはonのときは変数つかわず 関数リテラルを使うというのもありなのかもしれません
不便にはなりますが strictモードみたいなバグ減らすために機能を制限するって考え方もありますしね