Mixpanelをセットアップ中のエンジニアからのヘルプでハマりこんだ問題について。
mixpanel.track_formsでフォーム送信をトラッキングしたい
Mixpanelには、フォーム送信をフックして、ユーザーがフォーム送信したことをトラッキングする機能があるようです。
mixpanel.track_forms
track_forms関数を使って、対象のフォームに対してイベントをしかけます。この処理はフォームの送信をフックして、Mixpanelへトラッキング情報を送信します。そして、送信のコールバックで本来のフォーム送信を実行するというものです。
コールバックを待って本来の処理を実行するのではMixpanelのレイテンシが高くなるとサービスの動作に影響を与えるのではという心配がありますが、そこは300msくらいのしきい値でMixpanelへの送信をあきらめる機構も入っているそうです。
トラッキング後に本来のフォーム送信ができない
この関数を使うことで確かにMixpanelにトラッキング情報の送信ができました。が、本来のフォーム送信の動作が動かなくなりました。
エラー内容は以下。
TypeError: Property 'submit' of object #<HTMLFormElement> is not a function
Mixpanelのソースを流して読みすると、該当のコードは大雑把に以下のようなものです。
$('form').each(function(){
this.submit();
});
問題のソースコード
この現象を検証するために、HTMLを書きました。
これは動かない例なのですが、ごくありふれたformです。中に入力フォームと送信ボタンを置いています。
問題の原因は、送信ボタンにname=”submit”をつけていたことのようでした。どこでこの癖をつけてしまったのか覚えてないですが、僕は石器時代からつけていたような記憶があります。
formの中にsubmitというnameをもつ要素を置くと競合する
先のMixpanelの一部のコードはもっと簡単に書くと以下のような形になります。
$('form').get(0).submit();
そしてこれは以下のようなエラーを吐きます。
TypeError: $(...).get(...).submit is not a function
Chromeだと以下のようなエラー。
TypeError: Property 'submit' of object #<HTMLFormElement> is not a function
これはなぜかというと、Javascriptのform変数の中のsubmit変数が、submitというname属性をもつフォーム要素によって上書きされてしまうことにあります。
実際にsubmitオブジェクトを吐かせてみます。
console.info($('form').get(0).submit);
submit変数が関数ではなく、フォーム要素になってしまっています。
submitというname属性をもつフォーム要素を置かない
正しくはこうです。
これでMixpanelの方も、無事に動きました。
この悪しき癖を早期に直したいと思います・・・。
コメント
[…] Javascriptからsubmit()関数でフォーム送信できない問題 […]