12

I currently have an ajax call after a user presses a button on my web page..

The problem is, that after submitting, there is a slight delay (as a second ajax call needs to complete to show the DIV) to avoid a slight lag.. I was wondering if it was possible to append the content to a 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>

The above is my current code configuration. Now, this does not work as expected. It does not add the submitted content to the DIV.. here is how it's displayed through my ajax call:

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);

and the call:

 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();

How do I append the text area to a HTML div after pressing the button so my script doesn't have to wait for a response from the newly posted status?


Update. When the button is submitted it calls the following code:

$(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'

        });
    });
});

To handle the ajax input

4

12 回答 12

7

苏菲。

首先,看看这个片段。

window.setInterval(function()
{
  $(function () 
  {
      ...   
  });
 }, 1000);

我猜这是 jQuery :) 这个结构

$(function() { somecode(); }); 

用于执行 somecode(); 当 DOM 达到“就绪”状态时。这意味着 - somecode() 只会在文档的“就绪”事件上执行一次,而这里的 setInterval 只是绑定该事件的函数执行。

您应该改用这种结构:

$(function () 
{
    window.setInterval(function()
    {

        somecode();

    }, 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();

实际上,这不会发送任何响应。如果这是所有代码,那么您应该添加

echo json_encode($Array); 

至少,得到任何回应。

第三:

$.ajax({  
    url: 'Ajax/AjaxStatuses.php', data: "", dataType: 'json', ....

dataType: 'json' 表示您应该从服务器发送一个有效的 JSON 字符串,如果不是 - “成功”函数将不会执行。

如果这没有帮助,您应该检查所有数据流以找到它们被破坏的地方。使用浏览器中的开发人员控制台查看 ajax 请求中的服务器和来自服务器的内容以定位问题,然后您将能够轻松解决问题。

我也有一些建议给你,让你的代码更干净:

尝试为这样的事情制作更具体的选择器:

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

只需为相应的输入添加一个 id (或类,如果你有很多按钮)属性,然后像这样:

$('#id').on('click', function () { ...

或者

$('.class').on('click', function () { ...

另外))尝试提取以下内容:

<input type='hidden' name='UserID' value="<?=$_SESSION['UserID']; ?>">

超出 HTML 结构,如果这不在表单内或者您使用 ajax。我明白了,你在 js 中使用 UserID,所以这里更好的解决方案是

<script type="text/javascript">
   var UserID = "<?=$_SESSION['UserID']; ?>";
</script>

请注意,这只是更好,但当然不是最佳的。谷歌“将变量从 php 传递到 js”并选择最佳解决方案:)

最后一个: 尝试发出单个 SQL 请求以从数据库中获取数据。例如:

"SELECT UserID, Text FROM statuses Order BY ID DESC" 

"SELECT Username FROM users WHERE ID=?" 

您可以替换为:

"SELECT statuses.UserID, statuses.Text, users.Username
FROM statuses 
INNER JOIN users ON users.ID = statuses.UserID
Order BY ID DESC" 

这将通过减少数据库请求的数量来提高性能。

于 2013-07-08T10:35:51.620 回答
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();参数async:false,但我不推荐它。

于 2013-07-09T06:29:39.847 回答
2

似乎$('#output')缺少了。添加到您的 HTML 中:

<div id="output"></div>

如果是这种情况,您会注意到开发者控制台中存在 JavaScript 错误。

于 2013-05-27T04:11:00.993 回答
2

您似乎没有阅读要附加的正确数据。您正在从输入元素读取,但您应该从 textarea 读取。

看看这个,非常基础:http: //jsfiddle.net/ABFV9/

所以你想要的是通过以下方式从 textarea 获取提交的数据:

var getText=jQuery("[name='Status']").val();
于 2013-05-28T11:32:56.180 回答
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 回答
2

不要让表单“点击时”自动提交(您可以从表单属性中删除操作字段)。让 AJAX 调用发生并添加$("#YourFormIdHere").submit();为 ajax 调用中成功回调函数的最后一行(此处为 for 循环之外)。它应该工作。

于 2013-05-28T11:47:46.390 回答
2

您确定在同步或异步 AJAX 请求之间使用了正确类型的请求吗?

  • 使用同步请求,您正在等待服务器的回复。因此,在某些情况下,您可能会超时并且没有响应。
  • 使用异步请求,您无需等待回复。响应将在服务器回复时处理。

查看其他帖子:jQuery:执行同步 AJAX 请求

希望有帮助。

于 2013-07-08T13:16:32.337 回答
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

当您调用 statusupdate 查询时,您应该返回以 JSON 编码的用户和状态,然后您的函数 JQuery 中的回调允许解码 JSON 并附加到您的 div

1) 在 statusupdate.php

return json_encode('status:{'.$Array.'});

2)jQuery中的回调

$.ajax{(
)}.done(function(status) {
  var status = jQuery.parseJSON(status);
  Userstatus = status.text;
  UserName = status.username;
});

3) $('#output').append('<div class="status"><span>'+User +':</span><a href="#">'+UserName+'<span><strong>'+Userstatus+'</strong></span></div>');

于 2013-06-06T21:53:32.700 回答
1

Pajax 是使用 ajax 响应更新页面内容的简单解决方案,它将避免大量重复步骤,只需检查以下链接

还可以考虑使用模板生成 html,它们是用 json 数据填充 html 的漂亮且更短的方法

  • javascript模板:http ://handlebarsjs.com/
  • php 端模板:https ://github.com/bobthecow/mustache.php (如果您决定在 php 后端生成 html)
于 2013-07-13T09:58:41.103 回答
1

这里可能有很多问题。我将从一些调试技巧开始这个答案,然后列出要检查的地方。

一些调试技巧:

  • 在你的代码中抛出一些debugger;语句
  • 在 chrome 中打开开发者工具并让你的 javascript 通过那个代码路径,例如点击一个按钮。代码将在调试器语句处停止。
  • 调查传入和传出各种函数的值。确认关于被调用的各种函数以及它们接收到什么信息的假设。

检查的地方:

  • 确保您的 ajax 回调实际上正在运行。服务器的 mime 类型应该是 application/json。如果您的 ajax 回调没有运行,则可能是 mime/response 输入问题或某种服务器故障。
  • 确保 $('#output') 返回一些东西。尝试打开 chrome 控制台并在您使用其中一种debugger;语句暂停时输入。您应该取回一个 HTML 元素。
  • 您更新的代码并未向我表明在 ajax 调用完成后会发生任何事情。这是故意的吗?success如果您希望之后发生某些事情,您应该指定一个参数。
于 2013-07-09T01:28:19.710 回答
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 如果您需要更多帮助,如果我误解了这个问题,请在评论中告诉我 :)

干杯

普拉奈

于 2013-07-14T22:41:20.600 回答