2016-10-20 2 views
1

私はCodeIgniterで簡単なチャットモジュールを構築しようとしています。setTimeoutとclearTimeoutを使ってJSで再帰関数を再起動するには?

var last_id = 1; 

     $(document).ready(function(){ 
      loadMsgs(); 
      $("#content").focus(); 
      $("form#chatform").submit(function(){ 

       $.post("<?php echo base_url() ?>index.php/msg/update",{ 
          message: $("#content").val(), 
          con_id: <?php echo $con['conversation_id'] ?> 
          }, function(){ 
           $("#content").val(""); 
           $("#content").focus(); 

           loadMsgs(); 
       });  
       return false; 
      }); 
     }); 

     function loadMsgs() { 
      $.getJSON('<?php echo base_url() ?>index.php/msg/backend/<?php echo $con['conversation_id'] ?>/' + last_id, function(json) { 
       $.each(json, function(i,val){ 
        //console.log(val.id); 
        if(<?php echo $login_id ?> == val.sender_id){ 
         $("#messagewindow").append('<div class="bubble"><p>' + val.msg + '</p></div>'); 
        } else { 
         $("#messagewindow").append('<div class="bubble bubble-right"><p>' + val.msg + '</p></div>'); 
        } 
       }); 
       updateScroll(); 
       var newIndex = json.length-1; 
       if(typeof(json[newIndex]) != 'undefined'){ 
        last_id = json[newIndex].msg_id; 
       } 
       setTimeout('loadMsgs()', 4000); 
      }); 
     } 
     function updateScroll(){ 
      var element = document.getElementById("messagewindow"); 
      element.scrollTop = element.scrollHeight; 
     } 

私は、データベースからの最後のメッセージをつかむコントローラを要請し、その後#messagewindowするためにそれらを追加する$ .getJSONを使用した機能loadMsgsを持っています。コールバックの最後のものはsetTimeoutで、hatは4秒ごとに更新されます。

送信アクション私は、コントローラとコールバックでloadMsgsを再度呼び出す新しいメッセージを投稿します。その結果、私が新しいメッセージを提出するたびに、追加のコールが追加され、それはうまくいきません。

別のメッセージを送信した後でloadMsgsを再度呼び出す前に、グローバル変数idを追加してclearTimeoutを試してみました。var id = setTimeout('loadMsgs()', 4000);added clearTimeout(id);を変更しました。しかし何も変わりません。

答えて

2

あなたはグローバル変数idを持って、そして、あなたのハンドラであなたが

var id = setTimeout('loadMsgs()', 4000); 

を呼び出している場合は、グローバルidに触れることはありませんしています。

もう一度あなたのハンドラにvarを設定することによって、idの別の(そして別の...)コピーを定義し、それぞれにタイムアウトを設定します。 VarはNEW変数を定義し、それを繰り返し実行しているように見えます。ハンドラ内でvarを取り出し:

clearTimeout(id); 
id = setTimeout('loadMsgs()', 4000); 
+0

はい、これは私の間違いでした。しかし、私は奇妙な何かに気づいた。グローバルな 'var id;'定義では、私が提出するたびに追加の呼び出しを得ることができます。私がその行を削除するとき、私は望みの動作を得ました - すべてのサブミットの後に、タイマーはリセットされ、4秒後に次のコールを呼び出します。それが動作している間、私はそれが動作する理由を理解していない!私はidをグローバル化していないので、2つの関数がそれを使うことはできません。また、私はdeclered idでもhavent!私のコードには 'var id'という場所はありません。これを理解するのを助けてくれますか? –

+1

関数内で 'var id = ...'を宣言すると、それはその関数のローカルです。しかし、あなたが 'var'をスキップして' id = ... 'を置くと、意図せずにグローバル変数になりました。直感的ではない、私は知っている。 'js variable scope(変数スコープ)'を学ぶと、1時間ほどでスピードアップできます。他の言語ほど直感的ではありませんが、一度学習すれば設定されます。 –

1

これを解決するための簡単な方法は、あなたが提出する時に、それを呼び出したときにloadMsgsに引数を渡すことです。次に、この議論の存在をテストします。 ?アクションを提出し、新しいメッセージを自動的に取り込むために4秒JSONにそれを残してから)あなたはloadMsgsを(削除した場合はどうなり

$("form#chatform").submit(function(){ 
    // ... 

     loadMsgs(1); 
    // ... 
}); 

function loadMsgs(submitting) { 
    // ... 


    if (!submitting) setTimeout(loadMsgs, 4000); 
    // ... 
} 
0

:それが存在する場合は、のsetTimeoutを呼び出すことはありませんか。 JSを使用して、送信からの新しいメッセージのダミーコンテナを作成しますが、新しいJSONがキャプチャされたときにそのダミー要素をクリアしますか?

関連する問題