アプリ版:「スタンプのみでお礼する」機能のリリースについて

formのsubmitイベントの発生についての質問です。
あるところで、「form.submit() は submit イベントを発火しない」
とあったので、
↓のscriptで、formのsubmitイベントを調べていました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SessionTestNext</title>
<style type="text/css"></style>
<script type="text/javascript">

function send1(elm){
 elm.form.submit();
}

function send2(){
 document.getElementById("form1").submit();
}

if('undefined' !== typeof document.addEventListener){
 document.addEventListener('submit', function(event){
  var target = event.target;
  alert(target.id);
 }, false);
} else if ('undefined' !== typeof document.attachEvent){
 document.attachEvent('onSubmit', function(event){
 var target = event.srcElement;
 alert(target.id);
 });
}

</script>
</head>
<body>
<p>SessionTestNext 1 </p>

<form id="form1" action="/php/session2.php" method="post" onsubmit="alert('Submited!');return false;">

<input type="text" name="parm2" value="fugafuga">

<input type="submit" value="サブミット">

<button onclick="send1(this)">Javascriptサブミット(1)</button>

</form>

<button onclick="send2()">Javascriptサブミット(2)</button>

</body>
</html>

だのに、
send1()を実行した時は、イベントが検知され'Submited!'がアラートします。
ただし、onsubmitのハンドラーでfalseを返してるので、サブミットしません。
send2()を実行した時は確かに、submitイベントは発生せず、'Submited!'の
アラート無しで、実際サブミットされます。
documentにaddEventListenerで追加したハンドラーの方でも、send1()の
時だけ検知され'form1'がアラートします。

 send1()で検知されるのは何故でしょう?

また、IEでも同様の動作なんですが、何故か document.attachEvent('onsubmit',
の方が、まったく動きません。(タイポかも)

A 回答 (4件)

こんにちは。


回答ではありませんが、質問を読んで興味を持ったので…
send1とsend2で挙動が違うとは思ってもみませんでした。確かにご質問の通りのようで不思議ですね。

こういうときは、まず仕様書を読み解くのが常道なんでしょうけれど、そういうのに関してはめっきり苦手なもので…
そのかわりに、ちょっと追加実験をしてみました。

◆send2と同様のsend3を追加して
function send3(){
 var evt = document.createEvent("HTMLEvents");
 evt.initEvent("submit", true, true);
 document.getElementById("form1").dispatchEvent(evt);
}
としてみると、Submited及びform1のalertが出るようになります。
send1と同じような状態と考えてよいのかも。(IE系は未テスト)

実はその前に、form内にfocusを移してからsubmitしてみたり、this値にformを入れてthis.submit()のようにしたりと試してみたのだけれど、こちらはsend2と変わらないようでした。


◆document.attachEvent('onsubmit'~に関して
試しに
 document.getElementById("form1").attachEvent('onsubmit'~
としてみると、反応するようになります。
(想像ではIEではsubmitはバブルしないということなのでは?)

ただし、さすがにIEさん。反応が違ってくれてます。(IE6で試しました)
input押下げの時にはform1のalertが出るようになりますが、send1、send2ではでません。
(send3については、イベント発生の仕様を調べるのが面倒で試してません)
ということで、少なくともsend1の時の挙動が違う…


以上、まったく回答にはなっていませんが、少しは追加情報になるのではと…
きちんと、仕様書を紐解いてくださる方の出現を私もお待ちいたします。
    • good
    • 0
この回答へのお礼

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

>>こういうときは、まず仕様書を読み解くのが常道

今回は、SUBMIT()の仕様に気を取られ、<button>の仕様に目が
いきませんでした。

>>想像ではIEではsubmitはバブルしないということなのでは?

確かにそのとおりでした。

お礼日時:2010/08/20 12:45

#3 に補足。



> 「submitがイベントバブルしない」でFAなんですが、改めて調べてみると他にもバブルしないイベントが多数ありますね。(下記は一例で他にもあります)
正確には「DOM L2 Events でバブル可に指定されているイベントにも関わらず、IEでバブルしないイベントが多数ある」です。
文脈からわかるとは思いますが、念のため。
    • good
    • 0

#2 の続き。



> また、IEでも同様の動作なんですが、何故か document.attachEvent('onsubmit', の方が、まったく動きません。(タイポかも)
「submitがイベントバブルしない」でFAなんですが、改めて調べてみると他にもバブルしないイベントが多数ありますね。(下記は一例で他にもあります)

DOM L2 Events
http://www.y-adagio.com/public/standards/tr_dom2 …
onsubmit - MSDN
http://msdn.microsoft.com/ja-jp/library/cc410097 …
onchange - MSDN
http://msdn.microsoft.com/ja-jp/library/cc392240 …
onselect - MSDN
http://msdn.microsoft.com/ja-jp/library/cc392299 …

# DOM L2 に対応するらしい IE9 に期待したい!

---------

以下、サンプル。button要素で submit していることを確認できます。
(※全角空白は半角空白に置換してください)

<script type="text/javascript"><!--
function send (form) { form.submit(); }

if ('undefined' !== typeof document.addEventListener){
 document.addEventListener('submit', function (event) {
  var target = event.target;
  alert(target.id);
  event.preventDefault();
 }, false);
} else if ('undefined' !== typeof document.attachEvent) {
 document.getElementById('form1').attachEvent('onsubmit', function (event) {
  var target = event.srcElement;
  alert(target.id);
  event.returnValue = false;
 });
}
//--></script>
</head>
<body>
<form id="form1" action="/php/session2.php" method="post" onsubmit="alert('Submited 1');">
 <p><input type="text" name="parm2" value="fugafuga" /> <input type="submit" value="Submit" /> <button onclick="send(this.form);">button</button> <input type="button" onclick="send(this.form);" value="input[type=button]"></p>
</form>
<button onclick="send(this.ownerDocument.getElementById('form1'));">button</button>
<form id="form2" onsubmit="alert('Submited 1');"><p><button onclick="send(this.ownerDocument.getElementById('form1'));">button</button> <input type="button" onclick="send(this.form);" value="input[type=button]"></p></form>
    • good
    • 0
この回答へのお礼

全てのイベントがバブリングするわけじゃなく、
-バブリングするもの
-バブリングしないもの
-IEだとバブリングしないもの
があるんですね、以下は、受け売りですが

<イベントリスナを設置するときのガイドライン>
・バブリングするイベントタイプの場合、ルートノード(document)
 に addEventListener()
・バブリングしないイベントタイプの場合、HTML のイベント属性と
 して書く
・どうしても上記の手段がとれない場合、やむをえずレガシーなイ
 ベントプロパティを使う。


ですね。
最近ようやく、
キャプチャリング・フェーズ、ターゲット・フェーズ、バブリング・フェーズ
の意味と、addEventListener(,,true|false)の第3引数の意味が解ってきたような
(遅いっ!と言わないで)

お礼日時:2010/08/20 13:29

某所で解決しちゃっているような気もしますが、資料だけでも…。



> 「form.submit() は submit イベントを発火しない」
submit() メソッドが呼び出されると、submit実行時に「scripted-submitフラグ」がセットされます。

------
The submit() method, when invoked, must submit the form element from the form element itself, with the scripted-submit flag set.
http://www.whatwg.org/specs/web-apps/current-wor …
------

scripted-submitフラグがセットされていないならば、イベントを発火します。(4.)

------
When a form element form is submitted from an element submitter (typically a button), optionally with a scripted-submit flag set, the user agent must run the following steps:
...
3. If the scripted-submit flag is not set, and the submitter element's no-validate state is false, then interactively validate the constraints of form and examine the result: if the result is negative (the constraint validation concluded that there were invalid fields and probably informed the user of this) then abort these steps.
4. If the scripted-submit flag is not set, then fire a simple event that is cancelable named submit, at form. If the event's default action is prevented (i.e. if the event is canceled) then abort these steps. Otherwise, continue (effectively the default action is to perform the submission).
http://www.whatwg.org/specs/web-apps/current-wor …
------

> send1()を実行した時は、イベントが検知され'Submited!'がアラートします。
button要素におけるtype属性のデフォルトは submit ですので、正規の方法で submit してしまっています。
ですので、input[type="button"] なら、submitイベントが発火しません。

button 要素 - フォーム - HTML要素 - HTML5 タグリファレンス - HTML5.JP
http://www.html5.jp/tag/elements/button.html

> ただし、onsubmitのハンドラーでfalseを返してるので、サブミットしません。
Google Chrome 5 では submit してしまいました。
event.preventDefault(); (IEは event.returnValue = false;) した方がよさげです。

> send2()を実行した時は確かに、submitイベントは発生せず、'Submited!'のアラート無しで、実際サブミットされます。
そちらのbutton要素も type="submit" となりますが、this.form の参照先が form#form1 ではないので submit されないようです。
ちゃんと、form要素を書いてやれば、そちらの id を alert() します。

...(次の記事に続きます)...
    • good
    • 0
この回答へのお礼

資料のご提示ありがとうございました。

<button type="button" ....

としても、期待どおりでした。

お礼日時:2010/08/20 13:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!