- PR -

ボタン連打制御

投稿者投稿内容
ぼのぼの
ぬし
会議室デビュー日: 2004/09/16
投稿数: 544
投稿日時: 2005-09-02 15:33
こんにちわ〜。解決済みのとこすみません。
面白いことやってるな〜と思いつつもいい案が思いつかなかったのでROMってましたが、解決したにしろかなり複雑なことやってますよね。で、ちょっと代替案を思いついたのでご参考まで。

状況を整理すると、
・最終的な目的としては連打制御
・submitの前にsubmittableObject_Clickを走らせたい
・go();の処理は、実際には複数存在する
・これだけのことやってるからにはjavascriptがonなのは大前提

こんなとこでしょうか。で、気づいたことは、submittableObject_Clickという名前から察するに、複数あるgo();の類似関数は、途中の処理は違えど最終的には全てsubmitするのではないか、と。つまり、f1.submit();を最終的に書いている。

この前提で話を進めますが、このf1.submit();の部分を全て、例えばmySubmit();という関数に置き換えちゃいます。あとformタグもaction="view02.jsp"のとこをaction="javascript:mySubmit();"とします。で、

コード:

function mySubmit()
{
    if(submittableObject_Click()) {
        f1.action = "view02.jsp";
        f1.submit();
    }
}


みたいにすればonloadの処理は全て不要となり、随分シンプルになるのではないかな〜と。

思いついただけで試してませんが、念のため、私は識者ではありません(^^;
↑これって「ぬし」や「MVP」の方も皆さん仰りますよね。識者降臨求ムとか書かれると投稿しづらいっす。。。
葉瀬崎浩樹
大ベテラン
会議室デビュー日: 2005/06/28
投稿数: 115
お住まい・勤務地: 兵庫県
投稿日時: 2005-09-02 16:50
引用:
ぼのぼのさんの書き込み (2005-09-02 15:33) より:
念のため、私は識者ではありません(^^;
↑これって「ぬし」や「MVP」の方も皆さん仰りますよね。識者降臨求ムとか書かれると投稿しづらいっす。。。



あぅあぅ、おっしゃるとおりです。。
「早く助けて〜」ってつもりで書いてしまったのですけど、
閲覧してる方は参加しずらくなりますね。。
ちょっと熱くなってたので、そこまで気が回りませんでした。
#ビギナー回答者の為のガイドラインみたいなの作ろうかしら

で、解決済みのところ続けちゃいます。
解決の本命っぽい「attachEvent」を試してみました。
コード:

(略)elements[i].attachEvent('onclick', submittableObject_Click);



結果、go();→submittableObject_Click();の順に呼ばれました。
めでたしのはずです。


ただ、attachEvent()さらに繰り返すと、
関数の呼ばれる順番が狙ったとおりに行きませんでした。
こういうものなんですかね。

[自己レス]
IEの場合そういう動作のようです。
attachEvent 順番で検索
[/自己レス]

コード:

<html>
<head>
<title>attachEventを叩いて検証</title>

<script>
<!--

function go(){
alert('( ・∀・)マイヤフー');
}
function go2(){
alert('( ・∀・)マイヤホー');
}
function go3(){
alert('( ・∀・)マイヤハッハー');
}

window.onload = window_Load;

function window_Load() {
document.getElementById('btnNoma').attachEvent('onclick',go2);
document.getElementById('btnNoma').attachEvent('onclick',go3);
}
//-->
</SCRIPT>

</head>

<body>
<form>
<input type="button" id="btnNoma" value="( ・∀・)マイヤヒー" onclick="go();"></br>
</form>
</body>

</html>



#ブラウザによって、attachEventの順番が異なる点を追記。

[ メッセージ編集済み 編集者: 葉瀬崎浩樹 編集日時 2005-09-02 16:59 ]
ピンクの恐竜
常連さん
会議室デビュー日: 2005/02/01
投稿数: 42
投稿日時: 2005-09-02 18:13
ぼのぼのさん

返信ありがとうございます。

引用:

複数あるgo();の類似関数は、途中の処理は違えど最終的には全てsubmitするのではないか、と。つまり、f1.submit();を最終的に書いている。



申し訳ないです。
全て異なります。
物によってはlocation.replace( url );
物によってはlocation.href = url;
物によっては<a href="url"
物によってはform.submit
物によっては<input type="submit"
とさまざまです。
読んでいる場所も使い方もさまざまです

またsubmittableObject_Click();の名前ですが、
ここの過去ログに乗ってた処理をそのままコピーして使っていただけです。
まだ検証段階だったもので...。

まぎらわしくてすみません。



葉瀬崎浩樹さん

私もattachEvent()でいろいろ試して見ましたが同じ状況でした。
思ったとおりの順番で呼び出してくれなかったんですよね。

引用:

IEの場合そういう動作のようです。



そういうものなんですね。
ありがとうございます。
ぼのぼの
ぬし
会議室デビュー日: 2004/09/16
投稿数: 544
投稿日時: 2005-09-02 18:37
引用:

ピンクの恐竜さんの書き込み (2005-09-02 18:13) より:
申し訳ないです。
全て異なります。
物によってはlocation.replace( url );
物によってはlocation.href = url;
物によっては<a href="url"
物によってはform.submit
物によっては<input type="submit"
とさまざまです。
読んでいる場所も使い方もさまざまです


なるほどぉ。いっぱいありますねぇ…と言いたいところですが、整理するとそれ程「さまざま」でもありませんよこれ。
まず「form.submit」と「<input type="submit"」はmySubmitを通すことで解決します。モノによってactionやmethodが異なるなら、mySubmitに引数を増やせば良い。
そうすると残るのは「履歴を残すURL移動」と「履歴を残さないURL移動」の2種類だけです。これも1個関数を増やしてそれを通すようにすればいいんでは?

コード:

function myRedirect(url, historyFlg)
{
    if(submittableObject_Click()) {
        if(historyFlg) location.href = url;
        else location.replace(url);
    }
}



<a href="url" ⇒ <a href="javascript:myRedirect('url',true)"
location.href = url; ⇒ myRedirect(url,true);
location.replace(url); ⇒ myRedirect(url,false);

onloadで色々こねくりまわして思ったとおりの順番で呼び出してくれないと悩むよりはよっぽど簡単な気がするんですけど
ピンクの恐竜
常連さん
会議室デビュー日: 2005/02/01
投稿数: 42
投稿日時: 2005-09-02 19:29
ぼのぼのさん

提案ありがとうございます。

ただ今回の内容ですけどもちょっとした事情があります。
事情とは、
・既に画面は全て出来上がっている(当然Script等も)
・各画面でリクエストの投げ方はさまざま
・画面数は数百(Scriptの数でいうと500位?)
・今回の初めてボタン連打制御を入れる
です。

ぼのぼのさんがおっしゃるように一つ一つ修正するにはコストがかかるし(onloadで一括よりも)、
作業も単純作業なので処理の対応忘れ(抜け)の可能性が高くなります。

そのためonloadで一括で出来たら便利だと思い投稿させて頂きました。
He
大ベテラン
会議室デビュー日: 2002/12/18
投稿数: 141
投稿日時: 2005-09-03 10:10
皆さんこんにちは。
解決済みのところすみません。
興味深い話題なので、さらに話を続けてしまいます。

関数に別の関数を追加する方法ですが、
↓のような感じで実現できます。
コード:
<html lang="ja">
<head>
  <title></title>
  <script >
  // ★こんな感じ★
  function attachFunction(orgFunc, attFunc){
    return function(){
      attFunc();
      orgFunc();
    }
  }

  // 以下、使用例
  // 追加する関数
  function sampleFunction(){
    alert("SAMPLE");
  }
  
  function onload(){
    // ↓引数が長いので読みにくいですが、1行です。
    document.getElementById("elmA").onclick = 
      attachFunction(
        document.getElementById("elmA").onclick, 
        sampleFunction);
  }
  </script>
</head>
<body onload="onload();">
<input type="button" value="A" id="elmA" onclick="alert('A');">
</body>
</html>



ポイントは、関数を生成するときに、
Functionオブジェクトのコンストラクタではなく、
functionステートメントを使用しているところです。

実際に使用する場合は、引数のnullチェック等が必要になりますが、
基本的には、上記の方法でいけるとおもいます。

以上、参考になれば。

※上でもリンク張ってますが、Dynamic Scriptingさんのこの記事、非常に参考になります。

# ひっさしぶりのログインでした。
He
大ベテラン
会議室デビュー日: 2002/12/18
投稿数: 141
投稿日時: 2005-09-03 10:40
たびたびすみません。
Heです。

今回の要件に合うかどうかわかりませんが、
「各画面からのリクエストを1回だけにしたい」ということであれば、
↓のようなスクリプトでうまくいくかもしれません。
コード:
<script>
  window.onbeforeunload = function() {
    // ★ここにこのページからリクエストを送信できなくする処理を記述。
    //  例えば、アンカーやフォームを全てdisableにする処理など。
    //  以下は少し大胆なサンプル。
    document.getElementsByTagName("body").item(0).style.display="none";
  }
</script>


ご覧のとおり、onbeforeunloadを使ってますのでIE限定となります。
また、targetが自分自身以外の場合(他ウィンドウや他フレームの場合)は制御されません。
けど、シンプルかな、と。
まぁ、こんなアプローチもどうかなってことで。

あ、私も識者でありませんので悪しからず。
では、連投失礼いたしました。
ピンクの恐竜
常連さん
会議室デビュー日: 2005/02/01
投稿数: 42
投稿日時: 2005-09-03 15:50
返信ありがとうございます。

教えていただいたfunctionステートメントを使用する方法ですと、
少しすっきりした記述になりますね。
ありがとうございます。

onbeforeunloadの件ですがサンプルがほんとに大胆ですね。
ちょっとびっくりしました。

対象ブラウザはIE限定ですので、onbeforeunloadでも全くかまいません。

ただ今回教えていただいた方向性ですと、
・対象リンクまたはボタンを見えなくする、もしくは非活性にする。
だと思うのですが、
・画面の見た目は同じでボタンまたはリンクもクリックできる。
・だけども2回目押した場合はアラートが表示されリクエストが飛ばない。
という風には出来ないものなのでしょうか?

私もはじめのころはonbeforeunloadでいろいろ探してたのですが、
onbeforeunloadでreturnを使い処理を中断しようとすると
エンドユーザにわかりずらい確認ダイアログがでてしまい、
あきらめてました。

確認ダイアログをカスタマイズする。
または確認ダイアログを出さない方法は無いのでしょうか?

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