MySQL 数据无限滚动
Posted
技术标签:
【中文标题】MySQL 数据无限滚动【英文标题】:Infinite Scroll with MySQL Data 【发布时间】:2013-01-16 01:06:04 【问题描述】:我已关注此主题中的帮助:Using infinite scroll w/ a mysql Database
并且已经接近让它正常工作。我有一个使用 jquery masonry 以块显示的页面,其中块由 mysql 数据库中的数据填充。当我滚动到页面末尾时,我成功获得了 loading.gif 图像,但在图像之后立即显示 “没有更多帖子可显示。” 如果这是真的,它应该这样说。我最初只在大约 10-15 个帖子中调用了 5 个帖子,所以当我到达页面底部时应该加载其余帖子,但是当我真的没有更多帖子时,我会收到应该出现的消息帖子。
这是我的 javascript:
var loading = false;
$(window).scroll(function()
if($(window).scrollTop() == $(document).height() - $(window).height())
var h = $('.blockContainer').height();
var st = $(window).scrollTop();
var trigger = h - 250;
if((st >= 0.2*h) && (!loading) && (h > 500))
loading = true;
$('div#ajaxLoader').html('<img src="images/loading.gif" name="HireStarts Loading" title="HireStarts Loading" />');
$('div#ajaxLoader').show();
$.ajax(
url: "blocks.php?lastid=" + $(".masonryBlock:last").attr("id"),
success: function(html)
if(html)
$(".blockContainer").append(html);
$('div#ajaxLoader').hide();
else
$('div#ajaxLoader').html('<center><b>No more posts to show.</b></center>');
);
);
这是块实际所在页面上的 php。该页面最初发布了数据库中的 5 个项目。 javascript 获取最后发布的 id 并通过 ajax 将其发送到 blocks.php 脚本,然后使用最后发布的 id 从数据库中获取其余项目。
$allPosts = $link->query("/*qc=on*/SELECT * FROM all_posts ORDER BY post_id DESC LIMIT 5");
while($allRows = mysqli_fetch_assoc($allPosts))
$postID = $link->real_escape_string(intval($allRows['post_id']));
$isBlog = $link->real_escape_string(intval($allRows['blog']));
$isJob = $link->real_escape_string(intval($allRows['job']));
$isVid = $link->real_escape_string(intval($allRows['video']));
$itemID = $link->real_escape_string(intval($allRows['item_id']));
if($isBlog === '1')
$query = "SELECT * FROM blogs WHERE blog_id = '".$itemID."' ORDER BY blog_id DESC";
$result = $link->query($query);
while($blogRow = mysqli_fetch_assoc($result))
$blogID = $link->real_escape_string($blogRow['blog_id']);
$blogTitle = $link->real_escape_string(html_entity_decode($blogRow['blog_title']));
$blogDate = $blogRow['pub_date'];
$blogPhoto = $link->real_escape_string($blogRow['image']);
$blogAuthor = $link->real_escape_string($blowRow['author']);
$blogContent = $link->real_escape_string($blogRow['content']);
//clean up the text
$blogTitle = stripslashes($blogTitle);
$blogContent = html_entity_decode(stripslashes(truncate($blogContent, 150)));
echo "<div class='masonryBlock' id='".$postID."'>";
echo "<a href='post.php?id=".$blogID."'>";
echo "<div class='imgholder'><img src='uploads/blogs/photos/".$blogPhoto."'></div>";
echo "<strong>".$blogTitle."</strong>";
echo "<p>".$blogContent."</p>";
echo "</a>";
echo "</div>";
这是 AJAX 调用的 blocks.php 脚本中的 php:
//if there is a query in the URL
if(isset($_GET['lastid']))
//get the starting ID from the URL
$startID = $link->real_escape_string(intval($_GET['lastid']));
//make the query, querying 25 fields per run
$result = $link->query("SELECT * FROM all_posts ORDER BY post_id DESC LIMIT '".$startID."', 25");
$html = '';
//put the table rows into variables
while($allRows = mysqli_fetch_assoc($result))
$postID = $link->real_escape_string(intval($allRows['post_id']));
$isBlog = $link->real_escape_string(intval($allRows['blog']));
$isJob = $link->real_escape_string(intval($allRows['job']));
$isVid = $link->real_escape_string(intval($allRows['video']));
$itemID = $link->real_escape_string(intval($allRows['item_id']));
//if the entry is a blog
if($isBlog === '1')
$query = "SELECT * FROM blogs WHERE blog_id = '".$itemID."' ORDER BY blog_id DESC";
$result = $link->query($query);
while($blogRow = mysqli_fetch_assoc($result))
$blogID = $link->real_escape_string($blogRow['blog_id']);
$blogTitle = $link->real_escape_string(html_entity_decode($blogRow['blog_title']));
$blogDate = $blogRow['pub_date'];
$blogPhoto = $link->real_escape_string($blogRow['image']);
$blogAuthor = $link->real_escape_string($blowRow['author']);
$blogContent = $link->real_escape_string($blogRow['content']);
$blogTitle = stripslashes($blogTitle);
$blogContent = html_entity_decode(stripslashes(truncate($blogContent, 150)));
$html .="<div class='masonryBlock' id='".$postID."'>
<a href='post.php?id=".$blogID."'>
<div class='imgholder'><img src='uploads/blogs/photos/".$blogPhoto."'></div>
<strong>".$blogTitle."</strong>
<p>".$blogContent."</p>
</a></div>";
echo $html;
我尝试过使用 jquery 无限滚动插件,但这样做似乎要困难得多。我不知道这里有什么问题。我已经添加了警报并进行了测试,并且 javascript 脚本正在完全处理中,所以它必须与 blocks.php 一起使用吧?
编辑:我已通过将 sql 查询更改为 SELECT * FROM all_posts WHERE post_id < '".$startID."' ORDER BY post_id DESC LIMIT 15
这些块现在通过 ajax 加载,但是它们一次只加载一个块。 ajax 正在为每个块发送一个请求,并且它们一个接一个地淡入,是否可以使用 jquery masonry 使它们一次全部淡入?
【问题讨论】:
【参考方案1】:我在另一个答案中看到了您的代码,我建议在 MySql 中使用 LIMIT 功能而不是偏移值。示例:
SELECT * FROM all_posts ORDER BY post_id DESC LIMIT '".(((int)$page)*5)."',5
这只会在 AJAX 请求中获取页码并自动获取偏移量。这是一个一致的查询,并且独立于页面上的最后一个结果。在 jQuery 代码中发送类似 page=1 或 page=2 的内容。这可以通过几种不同的方式完成。
首先,计算页面上构建的元素数量,然后除以页面上的数量。这将产生一个页码。
其次,可以使用jQuery,将当前页码绑定到body:
$(body).data('page', 1)
每加载一个页面就加一。
这样做确实是更好的方法,因为它对所有操作使用一个查询,并且不需要关于页面上已有数据的大量信息。
唯一需要注意的是,此逻辑要求第一个页面请求为 0,而不是 1。这是因为 1*5 将计算为 5,跳过前 5 行。如果为 0,它将计算为 0*5 并跳过前 0 行(因为 0*5 为 0)。
如有任何问题,请告诉我!
【讨论】:
我最初有一个LIMIT
函数,如果你看一下我原来问题中的第三个代码块,它不是那样工作的,所以我做了 WHERE post_id < $startID
方法,它工作...但不完全是我想要的。每个 AJAX 请求它只抓取一个条目。您能否再解释一下您的方法,以便我尝试按照您的方式进行操作?
你有:LIMIT '".$startID."', 25 但这不一定是我们想要的。如果您传递 10 的起始 ID(因为假设您传递的是页面上可见的最后一个帖子)。这仅在每个 ID 都是连续的并且没有被跳过的情况下才有效。如果您删除了第 7 到 12 个帖子,则数据库中总共有 10 行。但是语句 LIMIT 12,25 将从第 12 行开始,该行不存在,并且不返回任何内容。 LIMIT 采用行偏移量并按此进行。它不会以任何方式在行中使用任何形式的 ID。 LIMIT 0,5 将从第 0 行(第一行)开始,持续 5 行。
哦!并且 LIMIT XX,25 将从第 XX 行开始并返回接下来的 25 行。如果您一次想要 5 行,我认为 25 应该是 5。
感谢您的精彩解释!我现在只有 5 个,因为我的数据库中还没有那么多项目。完成并填充后,我将希望一次提取大约 15-20 个条目。那么我应该如何构建您提到的页面查询呢?我的网站有一个分页脚本,但这是我几年前写的一个非常奇怪的分页脚本,我不明白它如何与你向我解释的内容一起工作......如果你不介意如果您愿意,我们可以通过电子邮件或这里帮助我...
页面上有计数器吗? masonryBlock 元素上的 COUNT 可能会起作用。 $(".masonryBlock").length 可以工作,因为它将获取页面上的当前项目数。您所要做的就是传递它,而不用担心任何其他 last_id 元素或任何东西。如果您有分页脚本,则可以传递页码并将其乘以每页显示的数量。你能把你的分页脚本开发成这样吗?您是否有权访问他们正在分页的页码?另外,我会给你发电子邮件。但是,让我们继续这样做吧。【参考方案2】:
您是否尝试过进行任何调试?
如果您还没有使用,我建议您获取 firebug 插件。
ajax 调用是否返回空?如果是这样,请尝试回显 sql 并验证这是正确的语句并且所有变量都包含预期的信息。考虑到客户端、服务器和数据库之间发生了很多通信,很多事情都可能失败。
作为对您的评论的回应,您在这段代码中添加了 html:
if(html)
$(".blockContainer").append(html);
$('div#ajaxLoader').hide();
我会在 if 语句之前执行 console.log(html) 和 console.log($(".blockContainer").length)。
【讨论】:
我将 sql 查询更改为$result = $link->query("SELECT * FROM all_posts WHERE post_id < '".$startID."' ORDER BY post_id DESC LIMIT 5");
,ajax 调用终于从数据库中引入数据,但现在 masonry 没有定位新添加的元素。
$(".blockContainer") 存在吗?
是的。那是所有砖石块所在的容器。以上是关于MySQL 数据无限滚动的主要内容,如果未能解决你的问题,请参考以下文章