使用Ajax进行页面滚动效果如何将数据加载到页面中

时间:2016-02-15 05:39:14

标签: javascript php jquery mysql ajax

我正在将mysql表中的数据加载到html表中。我正在使用AJAX php Jquery来实现这一目标。我需要确保无论表中有多少数据,我构建它的方式都能正常工作。

现在我正在使用一个5000行长的表,但这个表中最终会有88000行。

我知道如果我在页面加载时加载所有数据,这可能会导致服务器和页面的加载时间停滞不前。

我的问题是我的逻辑现在的方式是将所有结果加载到$ results中,并且只查询所需的行数,因为它是分页的。或者即使它是分页的,我的网页也会占用整个数据库中的每一行来加载时间。

如果正在加载整个表,我怎样才能将查询更改为仅在需要时加载数据。它加载页面滚动。

我还需要编写一个搜索功能。由于数据是分页的,我会在$ results中搜索数据还是使用单独的搜索功能查询表?哪种方式可以减少加载时间,从而导致用户体验不佳?

AjAX

<script type="text/javascript">
jQuery(document).ready(function($) {
var busy = true;
var limit = 5;
var offset = 0;
var assetPath = "<?php echo $assetPath ?>"

function displayRecords(lim, off) {
  jQuery.ajax({
          type: "GET",
          async: false,
          url: assetPath,
          data: "limit=" + lim + "&offset=" + off,
          cache: false,
          beforeSend: function() {
            $("#loader_message").html("").hide();
            $('#loader_image').show();
          },
          success: function(html) {
            $("#productResults").append(html);
            $('#loader_image').hide();
            if (html == "") {
             $("#loader_message").html('<button data-atr="nodata" class="btn btn-default" type="button">No more records.</button>').show()
            } else {
             $("#loader_message").html('Loading... Please wait <img src="http://www.wuno.com/monstroid/wp-content/uploads/2016/02/LoaderIcon.gif" alt="Loading">').show();
            }
            window.busy = false;

          }
        });
}

(function($) {
$(document).ready(function() {
if (busy == true) {
  displayRecords(limit, offset);
  busy = false;
}
});
})( jQuery );



(function($) {
$(document).ready(function() {
$(window).scroll(function() {
          // make sure u give the container id of the data to be loaded in.
          if ($(window).scrollTop() + $(window).height() > $("#productResults").height() && !busy) {
            offset = limit + offset;
         displayRecords(limit, offset);

          }
});
});
})( jQuery );
});
</script>

这就是我查询数据库的方式

$limit = (intval($_GET['limit']) != 0 ) ? $_GET['limit'] : 5;
$offset = (intval($_GET['offset']) != 0 ) ? $_GET['offset'] : 0;

$sql = "SELECT * FROM wuno_inventory WHERE 1 ORDER BY id ASC LIMIT $limit OFFSET $offset";
try {
  $stmt = $DB_con->prepare($sql);
  $stmt->execute();
  $results = $stmt->fetchAll();
} catch (Exception $ex) {
  echo $ex->getMessage();
}
if (count($results) > 0) {
  foreach ($results as $res) {
    echo '<tr class="invent">';  
    echo '<td>' . $res['wuno_product'] . '</td>';  
    echo '<td>' . $res['wuno_alternates'] . '</td>';  
    echo '<td>' . $res['wuno_description'] . '</td>';  
    echo '<td>' . $res['wuno_onhand'] . '</td>';  
    echo '<td>' . $res['wuno_condition'] . '</td>';  
    echo '</tr>';   
  }
}

3 个答案:

答案 0 :(得分:1)

通过从服务器传输JSON对象限制偏移 html (也许还有其他人 status_messsage 等)值可以同时转移到客户端。

在客户端,我的意思是这样的:

var limit = 5;
var offset = 0;
var assetPath = "<?php echo $assetPath ?>"

function displayRecords(lim, off) {
  jQuery.ajax({
      type: "GET",
      async: false,
      url: assetPath,
      dataType: "json",                         // We expect to receive a json object
      data: "limit=" + lim + "&offset=" + off,
      cache: false,
      beforeSend: function() {
        $("#loader_message").html("").hide();
        $('#loader_image').show();
      },
      success: function(json) {
        limit = json.lim;                       // corr to $output['lim']
        offset = json.offs;                     // corr to $output['offs']
        $("#productResults").append(json.html); // corr to $output['html']
        $('#loader_image').hide();
        if (json.html == "") {
         $("#loader_message").html('<button data-atr="nodata" class="btn btn-default" type="button">No more records.</button>').show()
        } else {
         $("#loader_message").html('Loading... Please wait <img src="http://www.wuno.com/monstroid/wp-content/uploads/2016/02/LoaderIcon.gif" alt="Loading">').show();
        }
        window.busy = false;

      }
    });
}

......在服务器端:

$limit = (intval($_REQUEST['limit']) != 0 ) ? $_REQUEST['limit'] : 5;
$offset = (intval($_REQUEST['offset']) != 0 ) ? $_REQUEST['offset'] : 0;

$sql = "SELECT * FROM wuno_inventory WHERE 1 ORDER BY id ASC LIMIT $limit OFFSET $offset";
// Make sure to handle invalid offset values properly, 
// as they are not validated from the last request.

// Prepare the $output structure (will become a json object string)
$output = array(
  'lim'=>$limit,
  'offs'=>$offset+$limit,
  'html'=>''
);
try {
  $stmt = $DB_con->prepare($sql);
  $stmt->execute();
  $results = $stmt->fetchAll();
} catch (Exception $ex) {
  $output['html'] .= $ex->getMessage();
}
if (count($results) > 0) {
  foreach ($results as $res) {
    $output['html'] .= '<tr class="invent">';  
    $output['html'] .= '<td>' . $res['wuno_product'] . '</td>';  
    $output['html'] .= '<td>' . $res['wuno_alternates'] . '</td>';  
    $output['html'] .= '<td>' . $res['wuno_description'] . '</td>';  
    $output['html'] .= '<td>' . $res['wuno_onhand'] . '</td>';  
    $output['html'] .= '<td>' . $res['wuno_condition'] . '</td>';  
    $output['html'] .= '</tr>';   
  }
}
// Now encode $output as a json object (string) and send it to the client
header('Content-type: application/json; charset=utf-8');
echo json_encode($output, JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_FORCE_OBJECT);

答案 1 :(得分:1)

我在我的网站http://www.flixnetforme.com/上做了你想做的事情,你可以看到当你滚动到页面底部时,下载了一组记录。我有超过150,000条记录,但当用户滚动到页面底部时,它只加载36条。

您希望这样做的方法是通过ajax加载您的第一个初始记录,而不是将它们硬编码到页面中。

<强>的index.php

$(document).ready(function(){
    var last_id;
    if (last_id === undefined) {
        genres = $("#genres").val();
        $.ajax({
            type: "POST",
            url: "includes/getmorefirst.php?",
            data: "genres="+ genres,
            success: function(data) {
                $( ".append" ).append(data);
            }
        });
    };
};

<html><div class="append"></div></html>

在此示例中,当用户访问页面并加载时,它会调用getmorefirst.php并返回第一个记录。

  • getmorefirst.php是一个文件,用于加载用户到达页面时要显示的第一组记录。在我的情况下,当用户滚动到我的页面底部时,我一次加载36条记录。

<强> getmorefirst.php

$sql = "SELECT * FROM table ORDER BY ID ASC LIMIT 36"
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)) {
    $last_id = $row['ID'];
    echo '<div>'.$row['column'].'</div>';
    echo '<div style="display:none" class="last_id" id="'.$last_id.'"';
}

last_id div很重要,这样ajax就会知道发送的最后一条记录,以及在加载下一组36条记录之后要记录的记录。

.append是div,当用户位于底部时,我将从ajax中追加数据。

.last_id是了解如何加载下一组记录的关键。无论你发送记录的顺序是什么,ajax都知道加载的记录的最后ID,所以它知道下次ajax调用更多记录时开始加载的位置。在我的情况下,用户滚动到页面底部。

当用户滚动到index.php的底部

if($(window).scrollTop() === $(document).height() - $(window).height()) {
        last_id = $(".last_id:last").attr("id");
        $.ajax({
            type: "POST",
            url: "includes/getmore.php?",
            data: "last_id="+ last_id,
            success: function(data) {
                $( ".append" ).append(data);
            }
        });
        return false;
    };
};

last_id = $(".last_id:last").attr("id");会收到最后一次ID

data: "last_id="+ last_id,会将最后一个ID发送给getmore.php,以便它知道发送记录的最后一个ID。

<强> getmore.php

$sql = "SELECT * FROM table WHERE ID > '$last_id' ORDER BY ID ASC LIMIT 36"
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)) {
    $last_id = $row['ID'];
    echo '<div>'.$row['column'].'</div>';
    echo '<div style="display:none" class="last_id" id="'.$last_id.'"';
}

正如您所看到的,getmore.php将返回接下来的36条记录,但在last_id发送之后。

希望这有意义并给你一个开始。

答案 2 :(得分:0)

以下是我测试过的JSON / AJAX机制的简化示例:

HTML(文件 test.html

<html>

<head>
<!-- THE NEXT LINE MUST BE MODIFIED -->
<script src="../jquery-1.4.3.min.js" type="text/javascript"></script>
<script type="text/javascript">
var limit = 5;
var offset = 0;
// THE NEXT LINE MUST BE MODIFIED
var assetPath = "http://www.example.com/stackoverflow/test.php"

function displayRecords(lim, off) {
    jQuery.ajax({
        type: "GET",
        url: assetPath,
        dataType: "json",                   // We expect to receive a json object
        data: "limit=" + lim + "&offset=" + off,
        async: true,
        cache: false,
        beforeSend: function() {
            $("#content").html("");
        },
        success: function(json) {
            limit = json.lim;                       // corr to $output['lim']
            offset = json.offs;                     // corr to $output['offs']
            $("#content").html(json.html);
            window.busy = false;
        }
    }); 
}
</script>
</head>

<body>
    <div id="content"></div>
    <div onclick="displayRecords(limit,offset); return false;" style="cursor:pointer">Click to Call</div>
</body>

</html>

PHP(文件 test.php

<?php
$limit = (intval($_REQUEST['limit']) != 0 ) ? $_REQUEST['limit'] : 5;
$offset = (intval($_REQUEST['offset']) != 0 ) ? $_REQUEST['offset'] : 0;

// Prepare the $output structure (will become a json object string)
$output = array(
'lim'=>$limit,
'offs'=>$offset+$limit,
'html'=>''
);

$output['html'] .= '<span style="color:red;">limit='.$output['lim'].', offset='.$output['offs'].'</span>';

// Now encode $output as a json object (string) and send it to the client
header('Content-type: application/json; charset=utf-8');
echo json_encode($output, JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_FORCE_OBJECT);

结果

1st time
第一次

2nd time
第二次

enter image description here第n次