jQuery.submit(handler) でイベントを登録しても、__doPostBack によるサブミット(ポストバック)では呼び出してくれない。
原因は、jQuery.submit(handler) は基本的にイベントリスナ(addEventListener, attachEvent)を使用し、__doPostBack はイベントリスナを考慮してないためである。
[一般的な __doPostBack の実装]
DOM の onsubmit プロパティは考慮してくれているが、イベントリスナについてはノータッチである。
(ざっと調べた感じ、イベントリスナのみの呼び出しはかなり面倒・・・というかできるか怪しい)
__doPostBack を使わないようにすれば問題ないのだが、asp:LinkButton や各種コントロールのイベント(SelectedIndexChanged など)を使ってしまうと、__doPostBack の使用は回避できない。
ただし、複数イベントの登録が面倒になる。
(onsubmit は function を 1 つしか登録できない)
[__doPostBack 上書き]
注意事項として、上記は event.preventDefault には対応してない。
event オブジェクトはクロスブラウザ対応が面倒なので・・・
また、aspx は <form runat=server> をページ内に 1 つしか定義できないため、theForm が複数あるなどの考慮は不要。
form.submit では登録したイベントは発生しないが、HTMLElement.click を使ってボタン押下をシミュレートすると、イベントを発生させることができる。
[form.submit 上書き]
注意事項として、onsubmit プロパティを使用している場合は、__doPostBack を使うとイベントが 2 回呼ばれてしまう。
jQuery.submit() でサブミットした場合も、jQuery で登録したイベントが 2 回呼ばれてしまう。
なので、これらは使わないようにするしかない。
副作用は大きいが、form.submit でイベントが発生して欲しい場合は、便利かもしれない。
逆に、イベントが発生しないサブミットは、form.submitOriginal を使用する。
原因は、jQuery.submit(handler) は基本的にイベントリスナ(addEventListener, attachEvent)を使用し、__doPostBack はイベントリスナを考慮してないためである。
[一般的な __doPostBack の実装]
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
DOM の onsubmit プロパティは考慮してくれているが、イベントリスナについてはノータッチである。
(ざっと調べた感じ、イベントリスナのみの呼び出しはかなり面倒・・・というかできるか怪しい)
__doPostBack を使わないようにすれば問題ないのだが、asp:LinkButton や各種コントロールのイベント(SelectedIndexChanged など)を使ってしまうと、__doPostBack の使用は回避できない。
解決手段① onsubmit プロパティを使用
__doPostBack の実装に合わせて、素直に onsubmit プロパティを使ってやれば問題ない。ただし、複数イベントの登録が面倒になる。
(onsubmit は function を 1 つしか登録できない)
解決手段② __doPostBack 上書き
javascript は関数の上書きができるので、__doPostBack を jQuery.submit(handler) を考慮する関数で上書きする。[__doPostBack 上書き]
if( typeof __doPostBack === 'function' && typeof theForm === 'object' ){
var __doPostBackOriginal = __doPostBack;
__doPostBack = function(eventTarget, eventArgument){
if( $(theForm).triggerHandler('submit') !== false ){
// イベントが登録されてない場合は undefined が返ってくるので厳密比較
// イベントで false を返せば、サブミットは実行されない
__doPostBackOriginal(eventTarget, eventArgument);
}
};
}
注意事項として、上記は event.preventDefault には対応してない。
event オブジェクトはクロスブラウザ対応が面倒なので・・・
また、aspx は <form runat=server> をページ内に 1 つしか定義できないため、theForm が複数あるなどの考慮は不要。
解決手段③ form.submit 上書き
上記と似ているが、今度は大元である form.submit を「サブミットボタン押下」の挙動に変更する。form.submit では登録したイベントは発生しないが、HTMLElement.click を使ってボタン押下をシミュレートすると、イベントを発生させることができる。
[form.submit 上書き]
// 全 form 対象
[].forEach.call(document.forms, function(f){
f.submitOriginal = f.submit;
f.submit = function(){
// 非表示のサブミットボタンを追加 -> 押下 -> 削除
$('<input type="submit" name="_適当な重複しにくい名前_" style="display:none" />')
.appendTo(f).click().remove();
};
});
注意事項として、onsubmit プロパティを使用している場合は、__doPostBack を使うとイベントが 2 回呼ばれてしまう。
jQuery.submit() でサブミットした場合も、jQuery で登録したイベントが 2 回呼ばれてしまう。
なので、これらは使わないようにするしかない。
副作用は大きいが、form.submit でイベントが発生して欲しい場合は、便利かもしれない。
逆に、イベントが発生しないサブミットは、form.submitOriginal を使用する。
0 件のコメント:
コメントを投稿