12

button現在、ユーザーがWeb ページでa を押した後、ajax 呼び出しが発生しています。

問題は、送信後、わずかな遅延を回避するために、わずかな遅延が発生することです (DIV を表示するには 2 番目の ajax 呼び出しを完了する必要があるため)。コンテンツを DIV に追加できるかどうか疑問に思っていました:

    <textarea name='Status'> </textarea>
    <input type='hidden' name='UserID' value="<?=$_SESSION['UserID']; ?>">
    <input type='button' value='Status Update'>
  <script>
  $(function () {
    $('input').on('click', function () {
        var Status = $(this).val();
       $('#output').append(Status);
});
  </script>

上記は私の現在のコード構成です。現在、これは期待どおりに機能しません。送信されたコンテンツは DIV に追加されません。ここに、私の ajax 呼び出しで表示される方法を示します。

window.setInterval(function()
{
  $(function () 
  {
    $.ajax({                                      
        url: 'Ajax/AjaxStatuses.php', data: "", dataType: 'json',  success: function(rows)        
        {
        $('#output').empty();
            for (var i in rows)
            {
                var row = rows[i];          
                var User = row[0];
                var Status = row[1]
                    $('#output').append(''+
                    '<div class="small-3 large-2 columns "><img src="http://placehold.it/80x80&text=[img]" /></div>'+
                    '<div class="small-9 large-10 columns">'+
                        '<p><strong><a href="#">'+User+'</a>:</strong>'+Status+'</p>'+
                        '<ul class="inline-list">'+
                            '<li><a href="">Reply</a></li>'+
                            '<li><a href="">Share</a></li>'+
                        '</ul><hr>');
            } 
        } 
    });       
  });
 }, 1000);

そして呼び出し:

 include "../PHP/Database.php";
    $Array = array();

        $Query = $DB->prepare("SELECT UserID, Text FROM statuses Order BY ID DESC");
        $Query->execute();
        $Query->bind_result($ID, $Text);
        $Query->store_result();
        while($Query->fetch()){
            $Second_Query = $DB->prepare("SELECT Username FROM users WHERE ID=?");
            $Second_Query->bind_param('i',$ID);
            $Second_Query->execute();
            $Second_Query->bind_result($Username);
            $Second_Query->fetch();
                $Array[] = array ($Username, $Text);
            $Second_Query->close();         
        }
        $Query->close();

ボタンを押した後にテキスト領域を HTML div に追加して、スクリプトが新しく投稿されたステータスからの応答を待つ必要がないようにするにはどうすればよいですか?


アップデート。ボタンが送信されると、次のコードが呼び出されます。

$(function () {
    $('input').on('click', function () {
        var Status = $(this).val();
        $.ajax({
            url: 'Ajax/StatusUpdate.php',
            data: {
                userid: $("input[name=UserID]").val(),
                text: $("textarea[name=Status]").val(),
                Status: Status
            },
            dataType : 'json'

        });
    });
});

ajax 入力を処理するには

4

12 に答える 12

2

私はあなたのコードからデモを行いました。問題が解決することを願っています。とにかく、jQuery と JavaScript のコーディング スタイルについて少し時間を割いて読むことをお勧めします。

まず、ボタンをクリックした後にステータスを更新するコードを修正します。

<!-- TEXTAREA that we will update --> 
<textarea name='Status'> </textarea>

<!-- I didn't saw output DIV in your code. It should be present in HTML -->
<div id='output'></div>

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>

<script>

 $(function(){

   // 1. Update on click:
   $('input').on('click', function () {

       var Status = $(this).val();

       // append content to the DIV
       $('#output').append(Status);

       // save content to the TEXTAREA
       $('textarea').val(Status);
   });

 }

</script>

AJAX リクエストを作成するコードも、それほど問題ないように見え、ほとんど機能していました。私はそれにいくつかの変更を加えました:

<textarea id='status' name='Status'> </textarea>
<div id='output'></div>
<input type='button' value='Status Update'>

<script id="AjaxStatusesTemplate" type="text/template">

  <div class="small-3 large-2 columns ">
    <img src="http://placehold.it/80x80&text=[img]" />
  </div>
  <div class="small-9 large-10 columns">
      <p><strong><a href="#">{{User}}</a>:</strong>{{Status}}</p>
      <ul class="inline-list">
          <li><a href="">Reply</a></li>
          <li><a href="">Share</a></li>
      </ul>
      <hr/>
   </div>

</script>

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>

<script>

    // 2. Update by timer with 1 second delay: 
    function UpdateOutputWithAjaxStatuses(){
        var htmlTemplate = $('#AjaxStatusesTemplate').html();
        $.ajax({ url: 'http://your-server.com/Ajax/AjaxStatuses.php', data: '', dataType: 'json',
          success: function(rows){
            $('#output').empty();
            for (var i=0, row=rows[i]; i<rows.length;i++)
            {     
              var User = row[0];
              var Status = row[1];

              var html = htmlTemplate
                           .replace('{{User}}', User)
                           .replace('{{Status}}', Status);

              $('#output').append(html);
            } 
          },
          error: function(){
              var now = new Date();
              $('#output').html('error at '+now);
          },
          complete: function(){
            setTimeout(UpdateOutputWithAjaxStatuses, 1000);
          }
        });       
    }

    // comment next line to stop autostart for ajax request scheduler
    UpdateOutputWithAjaxStatuses();

</script>

ここで実際の例を見つけることができます: http://jsfiddle.net/vmysla/XWuDf/6/

(AJAX リクエストを機能させるには、URL を変更する必要があります)

于 2013-07-12T21:13:48.537 に答える
2

setInterval は何のために必要ですか?

あなたの質問にできるだけ簡単に答えます。textarea を div に追加するには、クリック イベントをボタンにバインドする必要があります。簡単にやりたい場合は、次のように記述できます。

<script>
$(function (){
  $("#btn_append").click(function (){
     //$("#output").html($("#mytext").val()); //overwrite text
     $("#output").append($("#mytext").val()); //append text
  });
});
</script>
<input type="button" id="btn_append" value="append" />
<textarea id="mytext"></textarea>
<div id="output"></div>

最初に宣言したドキュメント対応関数$(function (){})を見てください。 setInterval で複数回宣言しています。名前が互いに似ており、コードのデバッグが困難になるため、命名規則も確認する必要があります。

遅延について書きました。これらは AJAX のスタンドとしての非同期メソッドであるため、遅延があることは明らかです。いつでも同期呼び出しを行うことができます$.ajax();。paramに渡すだけで済みますが、async:falseお勧めしません。

于 2013-07-09T06:29:39.847 に答える
2

データベースから返されるステータスの数は?

正しいコード (ここに投稿された以前の回答を組み合わせたもの) があり、それでも遅延が存在すると思います。setInterval で行われた ajax 呼び出しが原因である可能性があります。新しいステータスを追加した後、イベント#outputの前にトリガーされたリクエストによって上書きされます。click

ボタンをクリックしたときに xhr リクエストを中止して間隔機能をクリアできないようにするには、次のようにします。

$(function(){


    // interval reference and jQuery XHR object
    var ajaxInterval, jqxhr;

    // initialize fetching data from server
    function startPolling() {
        stopPolling();
        ajaxInterval = setInterval( function() {
            jqxhr = $.ajax({                                      
                url: location.href, 
                data: {ajax: 1}, 
                dataType: 'json',  
                type: "GET",
                success: function(result)        
                {
                    // parse result and insert into #output
                    // ...
                } 
            });     
        }, 1000);
    }

    // clear interval and abort xhr request
    function stopPolling() {
        if(ajaxInterval)
            clearInterval(ajaxInterval);
        if(jqxhr)
            jqxhr.abort();
    }


    $('input').click(function(){

        // this prevents overwriting from old ajax call
        stopPolling();

        // insert into #output our new status
        var getText=jQuery("[name='Status']").val();
        $('#output').append('<div>'+getText+'</div>');

        // post status into server
        $.ajax({                                      
            url: location.href, 
            data: {ajax: 1, status: $("[name='Status']").val()}, 
            dataType: 'json',  
            type: "POST",
            success: function(result)        
            {
                // parse result and insert into #output here
                // ...

                // restart fetching data
                startPolling();
            } 
        });     
    });

    // start fetching data
    startPolling();
});

これは、phpfiddle でのその JavaScript の簡単なデモです (xhr リクエストが機能している): http://phpfiddle.org/lite/code/hn0-0e1

しかし、各リクエストでいくつのステータスが取得されるのだろうか? 取得済みのステータスを変数に保存し、最後に取得したステータスよりも新しいものだけをロードするほうがよいのではないでしょうか? Facebook と同じように、ウォールを開いている場合、X 秒ごとにウォール全体をリロードするのではなく、前回の呼び出し以降に追加されたステータスを取得するだけです。

ちょっとしたアイデア:

$(function(){


    // interval reference and jQuery XHR object
    var ajaxInterval, jqxhr;
    var statuses = [];

    // initialize fetching data from server
    function startPolling() {
        stopPolling();
        ajaxInterval = setInterval( function() {

            // get the newest stored id
            var lastStatusId = 0;
            if(statuses.length)
                lastStatusId = statuses[0].id;

            jqxhr = $.ajax({                                      
                url: location.href, 
                data: {ajax: 1, lastStatusId: lastStatusId}, 
                dataType: 'json',  
                type: "GET",
                success: function(result)        
                {
                    if(result.updateStatuses) {
                        // prepending the latest statuses to our variable
                        statuses = result.statuses.concat(statuses);
                        // merge repaint output
                        displayStatuses();
                    }
                } 
            });     
        }, 1000);
    }

    // clear interval and abort xhr request
    function stopPolling() {
        if(ajaxInterval)
            clearInterval(ajaxInterval);
        if(jqxhr)
            jqxhr.abort();
    }


    function displayStatuses() {
        var $output = $('#output');
        $output.empty();

        // parse statuses array of objects and 
        // insert the result in the #output
        // ...
    }


    $('input').click(function(){

        // this prevents overwriting from old ajax call
        stopPolling();

        // insert into #output our new status
        var getText=jQuery("[name='Status']").val();
        $('#output').append('<div>'+getText+'</div>');

        // get the newest stored id
        var lastStatusId = 0;
        if(statuses.length)
            lastStatusId = statuses[0].id;

        // post status into server
        $.ajax({                                      
            url: location.href, 
            data: {ajax: 1, status: $("[name='Status']").val(), lastStatusId: lastStatusId}, 
            dataType: 'json',  
            type: "POST",
            success: function(result)        
            {
                if(result.updateStatuses) {
                    // prepending the latest statuses to our variable
                    statuses = result.statuses.concat(statuses);
                    // merge repaint output
                    displayStatuses();
                }

                // restart fetching data
                startPolling();
            } 
        });     
    });

    // start fetching data
    startPolling();
});

したがって、php コードは次のようになります。

    $Query = $DB->prepare("SELECT Statuses.ID, Text, Username FROM statuses, users WHERE Username.ID = statuses.UserID AND statuses.ID > ? ORDER BY Statuses.ID DESC");
    $Query->bind_param('i',intval($_REQUEST['lastStatusId']));
    $Query->execute();
    $Query->bind_result($ID, $Text, $Username);
    $Query->store_result();
    $Array = array();
    while($Query->fetch()){
         $Array[] = array ('id'=>$ID,'username'=>$Username, 'text'=>$Text);
    }
    $Query->close();

    // are there any new statuses?
    $result['updateStatuses'] = false;
    if( count($Array) )
        $result['updateStatuses'] = true;

    $result['statuses'] = $Array;
    echo json_encode($Array);
于 2013-07-12T10:19:15.627 に答える
1

Pajax は、ページ上のコンテンツを ajax 応答で更新する簡単なソリューションです。多くの繰り返しの手順を回避できます。以下のリンクを確認してください。

また、html 生成にテンプレートを使用することを検討してください。それらは、json データで html を埋めるための美しく、より短い方法です。

于 2013-07-13T09:58:41.103 に答える
1

あなたの質問を誤解していたら申し訳ありませんが、これは比較的簡単に思えます。#output で、ステータスを含む別の div を作成します...次のように:

<div id = "output">
    <div id="statuses">
    ...
    </div>
<textarea name='Status'> </textarea>
<input type='hidden' name='UserID' value="<?=$_SESSION['UserID']; ?>">
<input type='button' value='Status Update'>
</div>

では、こちら

window.setInterval(function()
{
  $(function () 
  {
    $.ajax({                                      
        url: 'Ajax/AjaxStatuses.php', data: "", dataType: 'json',  success: function(rows)        
        {
        $('#output').empty();
        for (var i in rows)
        {
            var row = rows[i];          
            var User = row[0];
            var Status = row[1]
            $('#output').append(''+
                '<div class="small-3 large-2 columns "><img src="http://placehold.it/80x80&text=[img]" /></div>'+
                '<div class="small-9 large-10 columns">'+
                    '<p><strong><a href="#">'+User+'</a>:</strong>'+Status+'</p>'+
                    '<ul class="inline-list">'+
                        '<li><a href="">Reply</a></li>'+
                        '<li><a href="">Share</a></li>'+
                    '</ul><hr>');
        } 
    } 
});       
});
}, 1000);

そのように変更 $('#output').empty();すると$('#statuses').empty(); 、そもそもテキスト領域を削除することはありません! :D

QArea の投稿も参照してください。構文に他のエラーが多数あるため、ここで説明されています。:D さらに助けが必要な場合は、質問を誤解している場合は pr をコメントで教えてください :)

乾杯

プラネー

于 2013-07-14T22:41:20.600 に答える