0

バックグラウンド

私は自分のウェブサイト用に非同期コメントシステムを書いています。これを達成する方法についてのチュートリアルをたくさん読んだ後、私はゼロからそれを構築し始めました。コメントはJSONリクエストを使用して取得され、Javascript(jQuery)を使用して表示されます。ユーザーが新しいコメントを追加すると、それはフープを通過し、最終的にAJAXを介してバックエンドに送信され、そこでデータベースに追加されます。AJAXリクエストの成功セクションで、スクリプトにコメントを空にしてから、新しいリスト(新しい投稿を含む)を再プルして再表示しました。

問題

それはすべて素晴らしいことでしたが、ページがはるかに短くなり、ユーザーがページを表示している場所がはるかに長くなるため、混乱します。コメントリストの最後(コメントの追加フォームがある場所)までページを再調整してもらいたかったのです。また、追加ボタンを再度有効にします。追加ボタンをクリックすると無効になり、せっかちな人がスパムを送信するのを防ぎます。

$('#commentList').empty();
getComments('blog', $('input#blogId').val());
window.location = "#addComment";
$('#comAdd').removeAttr('disabled');

これは理論的にはすべてうまく機能しましたが、getComments関数が実行される前に、ブラウザーがそれ自体よりも進んでwindow.locationを処理しているように見えました。それで私はもう少し読んでそれをグーグルで検索しました、そして人々が(同様の問題のために)コールバック関数を使うように言っているようだったので、私はこれを思いつきました:

$('#commentList').empty();
getComments('blog', $('input#blogId').val(), function() {
    window.location = "#addComment";
    $('#comAdd').removeAttr('disabled');
});

これにより、FireFoxによるとjavascriptエラーは生成されませんが、コールバック関数内では何も機能していません。ボタンを再度有効にしたり、window.locationを変更したりすることはありません。

何か案は?それについて行くためのより良い方法は?見えないような明白なタイプミスはありますか?

ありがとう!

アップデート

コールバック関数は標準的なものだという印象を受けました。

function getComments(type, id)
{

    $.getJSON("/ajax/"+type+"/comments?jsoncallback=&id="+id, function(data) {
        for (var x = 0; x < data.length; x++)
        {
            var div = $("<div>").addClass("comment").appendTo("#commentList");
            var fieldset = $("<fieldset>");
            var legend = $("<legend>").addClass("commentHeader");
            if ( data[x].url == "" )
            {
                legend.text((x+1) + ' - ' + data[x].name);
            }
            else
            {
                $("<a>").attr({href: data[x].url}).text((x+1) + ' - ' + data[x].name).appendTo(legend);
            }
            legend.appendTo(fieldset);
            $("<div>").addClass("date").text(data[x].timestamp).appendTo(fieldset);
            $("<p>").addClass("comment").text(data[x].content).appendTo(fieldset);
            fieldset.appendTo(div);
        }
    });

}

これは、ドキュメントの準備ができたときに呼び出されます。すべてのコメントをプルして、#commentListdiv内に表示します。ユーザーがコメントを送信すると、PHPスクリプトに対してAJAXリクエストが実行され、データベースに新しいコメントが追加されます。これが成功すると、次のようになります。

$('#commentList').empty();
getComments('blog', $('input#blogId').val());
window.location = "#addComment";
$('#comAdd').removeAttr('disabled');

ページからすべてのコメントを削除します。JSONを使用して、コメントを再度要求します(ユーザーの新しいコメントを含む)。ページを#addCommentアンカーに移動します。ここに、新しいコメントが表示されます。コメントの追加ボタンを再度有効にします。

問題は、getComments関数がすべてのコメントをレンダリングする前に、ブラウザーがwindow.location行を実行するため、ページが大きくなるにつれて、ユーザーは新しいコメントの近くを見ていません。

4

2 に答える 2

2

ここでの問題は、getComments()関数(詳細が必要)にあると思います。コールバックである3番目の引数を指定していますが、関数は実際にコールバックを使用していますか?何してるの?

特定のjQuery関数はコールバックを提供しますが、これは自動機能ではありません。ユーザーがコメントを入力するのを待っている場合は、ユーザーが[完了]をクリックしたときなど、関連するイベントをトリガーする必要があります。

OK、これを試してください:

function get_comments(type, id, callback) {
  $.getJSON("/ajax/"+type+"/comments?jsoncallback=&id="+id, function(data) {
    for (var x = 0; x < data.length; x++) {
      var div = $("<div>").addClass("comment").appendTo("#commentList");
      var fieldset = $("<fieldset>");
      var legend = $("<legend>").addClass("commentHeader");
      if ( data[x].url == "" ) {
        legend.text((x+1) + ' - ' + data[x].name);
      } else {
        $("<a>").attr({href: data[x].url}).text((x+1) + ' - ' + data[x].name).appendTo(legend);
      }
      legend.appendTo(fieldset);
      $("<div>").addClass("date").text(data[x].timestamp).appendTo(fieldset);
      $("<p>").addClass("comment").text(data[x].content).appendTo(fieldset);
      fieldset.appendTo(div);
      if (typeof callback != 'undefined') {
        callback();
      }
    }
  });
}

注:ここでの違いは、$。getJSON()コールバックの最後に呼び出されるコールバックであるget_comments()に3番目の引数が提供されることです。それはあなたが望む適切な順序を与えるでしょう。

また、そのようなHTMLを作成するのではなく、ページに含め、必要に応じて非表示/非表示にすることをお勧めします。ダイナミックHTMLよりもパフォーマンスがはるかに高く、問題が少ない傾向があります(たとえば、$()。live()を使用しない限り、新しいHTMLには関連するイベントハンドラーがありません)。

編集:コメントに従ってコールバックをオプションにしました。上記のコードを使用すると、コールバックなしまたはコールバックなしで関数を呼び出すことができます。

于 2009-03-15T03:45:14.157 に答える
0

単純。リクエストを受信して​​情報を処理したら、ボタンを再度有効にしてアンカーに移動します。そのようです:

function getComments(type, id)
{
    // ADDED
    $('#commentList').empty();

    $.getJSON("/ajax/"+type+"/comments?jsoncallback=&id="+id, function(data) {
        for (var x = 0; x < data.length; x++)
        {
                var div = $("<div>").addClass("comment").appendTo("#commentList");
                var fieldset = $("<fieldset>");
                var legend = $("<legend>").addClass("commentHeader");
                if ( data[x].url == "" )
                {
                        legend.text((x+1) + ' - ' + data[x].name);
                }
                else
                {
                        $("<a>").attr({href: data[x].url}).text((x+1) + ' - ' + data[x].name).appendTo(legend);
                }
                legend.appendTo(fieldset);
                    $("<div>").addClass("date").text(data[x].timestamp).appendTo(fieldset);
                    $("<p>").addClass("comment").text(data[x].content).appendTo(fieldset);
                fieldset.appendTo(div);
        }

        // ADDED
        window.location = "#addComment";
        $('#comAdd').removeAttr('disabled');
    });
}

個人的な意見:すべてのコメントを取得するのではなく、特定の日付からコメントを取得してみませんか? ページをロードするときは、応答にサーバー時間を含めます。Javascript はこれを使用して、舞台裏でクエリを実行します (新しいコメントを自動的にチェックするため)。JSON 応答には、次の応答で使用される新しいサーバー時刻が含まれています。

削除されたコメントをどのように処理しますか? 簡単: データベース テーブルに deleted_on 列を作成し、クエリを実行して、新しい投稿と共に JSON 応答でそれを吐き出します。

提案: の代わりに#addcomment、タイムスタンプによる ID コメント。

于 2009-03-15T04:30:16.390 に答える