1

2人でチャットできる会話システムを作っています。メッセージを含む DIV ボックスを 2 秒ごとに更新する AJAX 関数を作成しました。

ユーザーがメッセージを書いた、これは意図したとおりに機能しています。AJAX 呼び出しがすぐに実行されないのはなぜですか?

// SET AUTORUN updateMessages() EVERY 2 SECONDS
$(document).ready(function() {
    var interval
    window.onload = function(){
        interval = setInterval('updateMessages()', 2000);
    };
});

// UPDATE #mail_container_conversation
function updateMessages() {
    $.ajax({
        type: "POST",
        url: "<?php echo site_url(); ?>mail/ajaxupdate/<?php echo $user; ?>",
        data: dataString,
         
        success: function(data){
            $("#mail_container_conversation").html(data);
        }        
    });
}


// SEND NEW MESSAGE
$(function(){
    $("#mail_send").submit(function(){
        dataString = $("#mail_send").serialize();
         
        $.ajax({
        type: "POST",
        url: "<?php echo site_url(); ?>mail/send",
        data: dataString,
         
        success: function(data){
            updateMessages();
            $(".mail_conversation_answer_input").val('');
        }
                  
        });
                 
        return false;
    });
});
4

5 に答える 5

2

コードの残りの部分が機能する場合、問題はおそらく次のコードにあります。

$(document).ready(function() {
    var interval
    window.onload = function(){
        interval = setInterval('updateMessages()', 2000);
    };
});
  1. window.onloadDOM 対応のコールバックで既にラップしているため、 にアタッチする必要はありません。
  2. への呼び出し内から一重引用符と括弧を削除しますsetInterval
  3. DOM 対応のコールバックは、関数を jQuery メソッドに渡すだけで短縮できます。

代わりにこれを試してください:

$(function () {
    setInterval(updateMessages, 2000);
});

さらなる改善 - AJAX で間隔を避ける:

AJAX を扱う場合、サーバーが応答するのに 2 秒以上かかると、サーバーへの呼び出しがスタックしてしまう可能性があるため、間隔の使用を避ける必要があります。setIntervalサーバーが応答する時間があったかどうかは気にせず、何があっても2秒ごとに呼び出し続けます.

代わりにタイムアウトを使用し、Ajax 呼び出しの完全なコールバックで新しいタイムアウトを開始することをお勧めします。

あなたの場合、次のようになります。

$(function () {
    // Make the first call immediately when the DOM is ready
    updateMessage();
});

function updateMessages() {
    $.ajax({
        type: "POST",
        url: "<?php echo site_url(); ?>mail/ajaxupdate/<?php echo $user; ?>",
        data: dataString,

        success: function(data){
            $("#mail_container_conversation").html(data);
            // Make a new call, 2 seconds after you've 
            // received a successful respose
            setTimeout(updateMessages, 2000);
        }        
    });
}
于 2013-01-24T10:18:29.590 に答える
2

setTimeout/関数には、文字列の代わりに関数を提供する必要がありますsetInterval。また、ウィンドウの読み込みイベントに間隔を設定する必要もありません。DOM の一部として準備しておくことができます。

$(function() {
    updateMessages(); // don't wait 2 seconds for first update
    setInterval(updateMessages, 2000); // update every 2 seconds
});

データが受信されていないときに posback が機能する限り、他のすべては期待どおりに機能するはずです(ref dataString)。

暗黙のグローバルを使用していることを認識し、それが大きな問題になる可能性がある理由を理解していただければ幸いです (dataStringもう一度参照してください)。

あなたのコードをどのように書き直すか

コード全体を次のように書き直して、暗黙のグローバル変数を削除dataStringし、追加の関数でグローバルスコープを汚染せず、setTimeout場合によっては問題になる可能性のある間隔の代わりに使用します(ただし、あなたの場合は2秒ごとにしか実行されないためです)追加の非常に複雑なクライアント側スクリプトの実行がない場合は問題になりません)

すべてを関数クロージャのローカル スコープ内に保持しました。

$(function() {

    var timeout = null;

    var form = $("#mail_send").submit(function(evt){
        evt.preventDefault();
        $(".mail_conversation_answer_input", form).val("");
        updateMessages();
    });

    var updateMessages = function() {

        // we don'w want submit to interfere with auto-updates
        clearTimeout(timeout);

        $.ajax({
            type: "POST",
            url: "<?php echo site_url(); ?>mail/send",
            data: form.serialize(),
            success: function(data){
                $("#mail_container_conversation").html(data);
                timeout = setTimeout(updateMessages, 2000);
            }
        });
    };

    // start updating
    updateMessages();

});

/mail/sendこのコードでは、何も投稿されていない (データがない) ときに、会話に空行を追加するのではなく、これが単なる更新呼び出しであることを認識していることをサーバー側 ( で処理) に理解させる必要があります。この機能では、サーバー側 URL を 2 つではなく 1 つだけ使用するようになりました。それでも 2 つ必要な場合は、次のコードでうまくいくはずです。

$(function() {

    var timeout = null;
    var url = {
        update: "<?php echo site_url();?>mail/ajaxupdate/<?php echo $user;?>",
        submit: "<?php echo site_url();?>mail/send",
        use: "update"
    };

    var form = $("#mail_send").submit(function(evt){
        evt.preventDefault();
        url.use = "submit";
        $(".mail_conversation_answer_input", form).val("");
        updateMessages();
    });

    var updateMessages = function() {

        // we don'w want submit to interfere with auto-updates
        clearTimeout(timeout);

        $.ajax({
            type: "POST",
            url: url[url.use],
            data: form.serialize(),
            success: function(data){
                $("#mail_container_conversation").html(data);
                url.use = "update";
                timeout = setTimeout(updateMessages, 2000);
            }
        });
    };

    // start updating
    updateMessages();

});
于 2013-01-24T10:19:20.060 に答える
1

問題は、サーバーupdateMessages()に送信しようとすることですが、関数が実行datastringされるまでこれは入力されません。.submit()

mail/ajaxupdateスクリプトが何を期待しているのかわからないので、そこに何を入れるべきかわかりません。何も起こらないときにこれが呼び出された場合、フォームデータはまったく必要ないと思われるので、空の文字列を指定できます。

Javascriptコンソールをチェックすると、シリアル化の試行に関するエラーメッセージが表示されると思いますundefined

于 2013-01-24T10:21:43.033 に答える
0

window.onloadin your document ready 呼び出しは必要ありません。

$(document).ready(function() {
    setInterval('updateMessages()', 2000);
});

それはそれを始めるのに十分なはずです。

現在のように、DOM の準備ができたら、ウィンドウが読み込まれるまで待つように要求していますが、その時点では既に読み込まれているため、何も起こりません。

于 2013-01-24T10:18:35.860 に答える
0

試してみてください

$(document).ready(function() {

  setInterval('updateMessages()', 2000);

});
于 2013-01-24T10:17:26.103 に答える