- PR -

ボタン連打制御

投稿者投稿内容
ピンクの恐竜
常連さん
会議室デビュー日: 2005/02/01
投稿数: 42
投稿日時: 2005-09-01 18:37
返信ありがとうございます。

申し訳ないのですがボタン連打制御の2種類の違いがよくわからなかったのですが、
意図としては1つのリクエストを投げて、そのレスポンスが帰ってくる前に別のリクエストを投げる事を防ぎたいと考えています。
たぶん「1.の制御」であってると思います。

主な目的といたしまして
・2重登録を防ぐ
・サーバーの負荷軽減
です。

今まで私がテストした内容は以下の通りです。
bodyにonUnloadで制御:結局リクエストが飛びます。要件に合いません。
bodyにonBeforeUnloadで制御:リクエストを飛ばさないことは出来るが、変なダイアログがでるため要件に合いません。
bodyにonClickで制御:go()の処理が流れてからsubmittableObject_Click()が流れる。

です。

onBeforeUnloadでダイアログをカスタマイズしたり、ダイアログを出さないようにするだけでも用件は満たせます。

(F5ボタン押下のことは今回は想定外です。)

なにか他によい方法があれば教えていただきたいと思います。
宜しくお願い致します。
葉瀬崎浩樹
大ベテラン
会議室デビュー日: 2005/06/28
投稿数: 115
お住まい・勤務地: 兵庫県
投稿日時: 2005-09-01 18:51
チャット化してきてますね。。

下記のように、Submitボタンを使用している場合は、
formのSubmitイベントを捕捉できるのでチェックできるのですが。。
コード:

<form onsubmit="return submittableObject_Click();">
<input type="submit" value="送信">
^^^^^^


困りましたね。。
識者の降臨が待ち遠しい(>_<)

[ メッセージ編集済み 編集者: 葉瀬崎浩樹 編集日時 2005-09-01 18:52 ]
葉瀬崎浩樹
大ベテラン
会議室デビュー日: 2005/06/28
投稿数: 115
お住まい・勤務地: 兵庫県
投稿日時: 2005-09-01 20:47
引用:

申し訳ないのですがボタン連打制御の2種類の違いがよくわからなかったのですが、
意図としては1つのリクエストを投げて、そのレスポンスが帰ってくる前に別のリクエストを投げる事を防ぎたいと考えています。
たぶん「1.の制御」であってると思います。

主な目的といたしまして
・2重登録を防ぐ
・サーバーの負荷軽減
です。



うーん。。
送信から再表示までの流れは大体こんな感じかと。
A:リクエスト送信
B:レスポンス待ち
C:ブラウザ上のHTMLドキュメント破棄(onUnload)
D:レスポンスされたHTMLの読み込み開始
E:読み込み完了

私の書いた2種類の制御とは、
以下のタイミングでの制御ついて述べたつもりです。
■D〜E時期のボタン連打制御
1.「ドキュメントの読込み完了までボタン押下させたくない」

■A〜B時期でのボタン連打制御
2.「送信後のレスポンス待ち時間中に、複数回ボタン連打されたくない」

認識にずれが無いか心配です。。汗

引用:

今まで私がテストした内容は以下の通りです。
bodyにonUnloadで制御:結局リクエストが飛びます。要件に合いません。
bodyにonBeforeUnloadで制御:リクエストを飛ばさないことは出来るが、変なダイアログがでるため要件に合いません。
bodyにonClickで制御:go()の処理が流れてからsubmittableObject_Click()が流れる。

です。



onUnloadは、ドキュメントの破棄タイミングで発生したと思います。
再読み込みやページ遷移、×ボタンで閉じるときにも発生するので
二重送信制御に使用するのは厳しいでしょう。

引用:

なにか他によい方法があれば教えていただきたいと思います。
宜しくお願い致します。



参考になるかどうかわかりませんが、
ASP.netで作成した制御の概要を紹介します。

■1.「ドキュメントの読込み完了までボタン押下させたくない」制御
→サーバが返すHTMLでは、ボタンのDisableプロパティを常にTrueにしておき、
 読み込み中はボタンを押せなくする。
→クライアント側のonLoadイベントを使って、Disableを変更する。

■2.「送信後のレスポンス待ち時間中に、複数回ボタン連打されたくない」 制御
→onSubmitが実行されたら、送信中フラグを立てる。
 送信中フラグが立っている間は、以降の送信をキャンセルする。

どこまで参考になるかわかりませんが。。

#情報が拡散してきたのでそろそろ交通整理が必要ですね〜。
#と、原因を作った張本人が言ってみる。。汗
todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2005-09-01 21:00
引用:

やりたい事としては次のようになります。
・onload時に全てのボタン、全てのリンクのonclickにsubmittableObject_Click()の処理を追加する。
・ボタンやリンクに直接onclickで書かれていた処理はsubmittableObject_Click()の処理が終わってから実行する。



ASP.NETならサーバーサイドでやるのがいいでしょう。
共通のPage派生クラスで、OnPreRenderをオーバーライドする。

しかし、質問はクライアントサイドの方法でしたね。

動的に関数オブジェクトを作成するか、
http://www.tohoho-web.com/js/function.htm#newFunction

独自クラスのメソッドを渡す
http://www.tohoho-web.com/js/object.htm

で出来るかもしれません。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-09-01 21:25

なんにしても、クライアントだけで何とかしよう、というのには反対。
…Ajax なんか言い出したら、JavaScript は有効にしておけ!!ってことになるのか??


んで、この現象ですが、onclick イベントを上書きしているからです。サーバから送られてきた onclick イベントを、JavaScript 内で上書きしてしまうため、元々あったものが実行されません。
# ってところはいいのね。。。

 現在の内容に追加するような処理が必要です。[投稿日時: 2005-09-01 17:29]分では、変更されたものを呼び出すような処理になっています。
 河端さんのサイトで紹介されていたのですが、フォーラムは閉鎖している?

 軽く調べてみたんですが、attachEvent で複数のイベントをアタッチできません?

 河端さんのところでやっていたのは、関数のオブジェクトをとってきて、toString() で展開して、関数オブジェクトを作って…みたいな感じでした。
コード:
こんな感じ
onclick = new function(onclick.toString() + "追加する内容");


もちろん、現在の onclick の内容を後からにするなら、順番を入れ替えます。

_________________
ピンクの恐竜
常連さん
会議室デビュー日: 2005/02/01
投稿数: 42
投稿日時: 2005-09-02 11:05
葉瀬崎浩樹さん
todoさん
Jittaさん
返信ありがとうございます。

頂いた意見から実際に私の方でも検証してみました。

まずnew functionでやる方法ですが、以下のようなものを作ってみました。
コード:
      document.forms[0].elements[i].onclick = new Function (
      	"submittableObject_Click();"+
      	"document.forms[0].elements["+i+"].onclick();");


そうしたら動くには動いたのですが、submittableObject_Click()の処理の無限ループ
に入ってしまいました。
どうやらonclickでみている先が現在のonclickのようです。

また関数オブジェクトを作成する方法では次のようなものを作ってみました。
コード:
--作成
function Func(execFunc) {
    this.exec = function () {
        submittableObject_Click();
        execFunc.call();
    }
}

--document.forms[0].elements[i].onclick = submittableObject_Click;のかわり
var func = new Func(document.forms[0].elements[i].onclick);
document.forms[0].elements[i].onclick = func.exec;


これはなぜか
submittableObject_Click⇒go⇒submittableObject_Clickと動いていました。
よくわかりません。

またattachEventですが、以下のように作ってみました。
コード:
      var fuc = document.forms[0].elements[i].onclick;
      document.forms[0].elements[i].onclick = submittableObject_Click;
      document.forms[0].elements[i].attachEvent("onclick",fuc);


これも動きがなぜか
submittableObject_Click⇒go⇒submittableObject_Clickと動いていました。
よくわかりません。


今回これらの関数?をはじめて使ったので調べながら作ったのですが、
作り方、または使い方はあっているのでしょうか?

どこを直せば期待した動きになるのでしょうか?
宜しくお願い致します。
葉瀬崎浩樹
大ベテラン
会議室デビュー日: 2005/06/28
投稿数: 115
お住まい・勤務地: 兵庫県
投稿日時: 2005-09-02 11:21
引用:
Jittaさんの書き込み (2005-09-01 21:25) より:
コード:

こんな感じ
onclick = new function(onclick.toString() + "追加する内容");




動的にfunctionを作れるのですね〜。
知らなかった(ぉ

引用:
ピンクの恐竜さんの書き込み (2005-09-01 16:06) より:
・onload時に全てのボタン、全てのリンクのonclickにsubmittableObject_Click()の処理を追加する。
・ボタンやリンクに直接onclickで書かれていた処理はsubmittableObject_Click()の処理が終わってから実行する。



では、実際にやってみましょう。
コード:

(略).onclick = new Function( "go();" + "submittableObject_Click();");


go()→submittableObject_Click()の順に処理されました。めでたし。

でも、ボタンやリンクによってgo()の処理は違う場合は、
"go();"って、固定で書けないのですよね?
go()以外の呼び出しもできるように、もっと応用の利く書き方にしないと。。

ということで、試行錯誤してみましたが。
go()にあたる関数の書き方がわからない。。
ええい、こうなったら関数オブジェクト自身を引数に渡してしまえ!
と書いたのが下のコード。
#.netのdelegateをイメージに近いかな?
#いや、単なるcallbackかも。。(独り言

コード:


(略).onclick = new Function(
"submittableObject_ClickVer2(" + variableFunc + ");"
);


// 二重送信制御(関数オブジェクトを引数に取るバージョン)
function submittableObject_ClickVer2(funcObject) {
if (isDocumentLoading()) {
alert("処理中です…");
return false;
}
//引数で指定された関数を実行
funcObject();

alert("submitを実行します");
return true;
}



このコードで、
1.submittableObject_ClickVer のメイン処理 
2.Go()に該当する処理
の順番で実行できました。
非常に見通しが悪くなりますが。。

もっとスマートな書き方などご存知でしたら、
ご指導よろしくお願いします。

#またスレ違ってた(>_<)

[ メッセージ編集済み 編集者: 葉瀬崎浩樹 編集日時 2005-09-02 11:32 ]
ピンクの恐竜
常連さん
会議室デビュー日: 2005/02/01
投稿数: 42
投稿日時: 2005-09-02 13:06
葉瀬崎浩樹さん
返信ありがとうございます。

葉瀬崎浩樹さんに記述していただいた方法でやりたい処理が出来ました。
ありがとうございます。

いままで助言していただいた方々どうもありがとうございました。

スキルアップ/キャリアアップ(JOB@IT)