あけましておめでとうございます、すぎたです。
本年もよろしくお願いいたします。

# 最近忙しくて、あまりアクセスできてないですが、(^^;;
# 時々見ています。

In message news:vKWzd.120$qv2.83@news1.dion.ne.jp
"ITAHASHI Kunio" <kunitahashi@h2.dion.ne.jp> wrote ...

> >if (nr<20) {setTimeOut('F()',100);}

> なるほど。
> システム関数自体に条件をつけることもできるわけですね。

というより、処理したい順に実行されるように、条件によって
処理を分岐して処理内容を変えているということです。

| var nr = 0
| function F(){ 
|   document.all('id1').innerHTML = nr++; 
|   setTimeout('F()',100); 
| }

| nrが20になったときに関数を無効にしたいのです。

上記の例だと、関数 F() は

  1) id1 の内容に nr を代入した後、nr に 1 を加える。
  2) 100ミリ秒後に関数 F() を呼び出すように、システムに登録する。

となります。

ここで、nr が 20 になったときに関数を無効にするということは、
「nr が 20 になったとき、100ミリ秒後に関数 F() を呼び出すように
システムに登録することを止める」と言えます。

nr が 20 になったときというのが、id1 に 20 が代入されたら
ということだとすると、代入後 1 が加算されて 20 を超えますので、

  1) id1 の内容に nr を代入した後、nr に 1 を加える。
  2) もし nr が 20 以下だったら、
       100ミリ秒後に関数 F() を呼び出すように、システムに登録する。
     そうでなかったら(20を超えていたら)
       なにもしない(システムに登録しない)

となり、これを JavaScript になおすと、

  var nr = 0;
  function F() {
    document.all('id1').innerHTML = nr++;
    if (nr <= 20) {
      setTimeout('F()',100);
    } else {
    }
  }

となり、else { } は処理内容が無いので、

    if (nr <= 20) {
      setTimeout('F()',100);
    }

となります。


> var nf = 20;
> var ng = 0;
> 
> function G(){
> if(ng<=21){
> document.all('id1').innerHTML = ++ng; 
> setTimeout('G()',500); 
> if(ng==21){F();}
> }
> }
> 
> function F(){ 
> if(nf>=0){
> document.all('id1').innerHTML = --nf; 
> setTimeout('F()',500); 
> if(nf==0){G();}
> }
> }
> 
> 
> 発想は単純なんですが、折り返してきて-1で止まって
> しまいます。どこがいけないのでしょうか。

これも、処理された内容を追うことで、なぜ止まってしまうかが
理解できる…と言いたいところですが、ちょっとややこしいこと
になっています。

まず、初期状態で nf=20, ng=0 となっており、最初に G() が
呼び出されることから、

  もし ng が 21 以下であれば、
    ng に 1 加算して、id1 に ng を代入する。
    500ミリ秒後に 関数 G() を呼び出すように、システムに登録する。
    もし ng が 21 と等しかったら、
      関数 F() を呼び出す。
    そうでなかったら(ng が 21 と等しくなかったら)、
      なにもしない。
  そうでなかったら(ng が 21 を超えていたら)、
    なにもしない

にしたがって、

   1) ng が 0 で、21 以下なので、1 を加算し id1 に代入。
   2) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
   3) ng が 1 で、21 と等しくないため、なにもしない。
   4) 500ミリ秒後に 関数 G() が呼び出される。
   5) ng が 1 で、21 以下なので、1 を加算し id1 に代入。
   6) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
   7) ng が 2 で、21 と等しくないため、なにもしない。
   8) 500ミリ秒後に 関数 G() が呼び出される。
    ......
  78) ng が 19 で、21 以下なので、1 を加算し id1 に代入。
  79) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
  80) ng が 20 で、21 と等しくないため、なにもしない。
  81) 500ミリ秒後に 関数 G() が呼び出される。
  82) ng が 20 で、21 以下なので、1 を加算し id1 に代入。
  83) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
  84) ng が 21 で、21 と等しいため、関数 F() を呼び出す。
  85) nf が 20 で、0 以上のなので、1 減算して id1 に代入。
  83) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
  84) nf が 19 で、0 と等しくないため、なにもしない。
  85) 500ミリ秒後に 関数 G() が呼び出される。
  86) ng が 21 で、21 以下なので、1 を加算し id1 に代入。
  87) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
  88) ng が 22 で、21 と等しくないため、なにもしない。
  89) 83) で登録した 関数 F() が呼び出される。
  90) nf が 19 で、0 以上のなので、1 減算して id1 に代入。
  91) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
  92) nf が 18 で、0 と等しくないため、なにもしない。
  93) 500ミリ秒後に、87) で登録した 関数 G() が呼び出される。
  94) ng が 22 で、21 を超えているため、なにもしない。
  97) 91) で登録した 関数 F() が呼び出される。
  98) nf が 18 で、0 以上のなので、1 減算して id1 に代入。
  99) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
 100) nf が 17 で、0 と等しくないため、なにもしない。
 101) 500ミリ秒後に 関数 F() が呼び出される。
    ......
 166) nf が 1 で、0 以上のなので、1 減算して id1 に代入。
 167) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
 168) nf が 0 で、0 と等しいため、関数 G() が呼び出される。
 169) ng が 22 で、21 を超えているため、なにもしない。
 170) 500ミリ秒後に 関数 F() が呼び出される。
 171) nf が 0 で、0 以上なので、1 減算して id1 に代入。
 172) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
 173) nf が 0 で、0 と等しいくないため、なにもしない。
 174) 500ミリ秒後に 関数 F() が呼び出される。
 175) nf が -1 で、0 未満のため、なにもしない。

のように動作しています。
(ここはちょっとややこしいことになってるので、あまり詳しく
 見なくても良いかもしれません)

問題点は2つあって、関数 G() と F() が二重に動作している
個所があることと、F() から G() に移るとき、ng が初期化
されずに 22 のままのため、169) でなにもせずに G() の動作
が停止している点です。

動作を G() と F() に分ける場合、

関数 G()
  もし ng が 20 未満であれば、
    ng に 1 を加算して、id1 に代入する。
    500ミリ秒後に 関数 G() が呼び出されるように、システムに登録。
  そうでなければ(20 以上であれば)、
    nf を 20 に初期化。
    関数 F() を呼び出す。

関数 F()
  もし nf が 0 より大きければ、
    nf を 1 減算して、id1 に代入する。
    500ミリ秒後に 関数 F() が呼び出されるように、システムに登録。
  そうでなければ(0 以下であれば)、
    ng を 0 に初期化。
    関数 G() を呼び出す。

とすることで、

  ng=0,G(),0,1,2,...,19,20,nf=20,F(),19,18,...,1,0,ng=0,G(),...

と、連続して動作することになります。

ここで重要なのは、相手の関数の動作に必要な条件を整えておく点で、
F() を呼び出すときは、変数 nf をあらかじめ初期化し、
G() を呼び出すときは、変数 ng をあらかじめ初期化する点です。

初期化には他の方法もあるのですが、本ケースでは、各関数の
を呼び出す前に初期化するのがわかりやすいかと思います。

-- 
杉田
sugi-nws@bk.iij4u.or.jp