通过无限的页面滚动,新的内容在滚动页面时动态地加载。
它是用户友好的,并提高了页面速度。
在本教程中,我展示了如何在Laravel 8项目中使用jQuery AJAX在页面滚动中加载MySQL数据库内容。
内容
1.数 据库配置
打开.env 文件。
指定主机、数据库名称、用户名和密码:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tutorial
DB_USERNAME=root
DB_PASSWORD=
2.创 建表
- 使用迁移创建一个新的表
posts,并添加一些记录:
php artisan make:migration create_posts_table
- 现在,从项目根目录导航到
database/migration/文件夹。 - 找到一个以
create_posts_table结尾的PHP文件并打开它。 - 在
up()方法中定义表的结构。
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->string('link');
$table->timestamps();
});
}
- 运行迁移
php artisan migrate
- 表已经被创建,并在其中添加一些记录。
3.模 型
- 创建
Posts模型:
php artisan make:model Posts
- 打开
app/Models/Posts.php文件。 - 使用
$filliable属性指定大量可分配的模型属性 - 标题、描述和链接。
完成的代码
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Posts extends Model
{
use HasFactory;
protected $fillable = [
'title','description','link'
];
}
4.路 线
- 打开
routes/web.php文件。 - 定义2个路由 -
- / -加载索引视图。
- /getPosts -这是用来处理页面滚动的AJAX请求。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostsController;
Route::get('/', [PostsController::class, 'index']);
Route::get('/getPosts', [PostsController::class, 'getPosts'])->name('getPosts');
5.5 .控制器
- 创建
PostsController控制器:
php artisan make:controller PostsController
- 打开
app/Http/Controllers/PostsController.php文件。 - 导入
Posts模型。
创建$rowperpage 类变量来存储一次获取的记录数量。我把它设置为4 ,你可以根据需求来改变它。
创建2个方法 -
- index() -将
$rowperpage赋给$data['rowperpage'],将posts表中的记录总数赋给$data['totalrecords'],从posts表中获取前4条记录并赋给$data['posts']。
加载index 视图并传递给$data 阵列:
- getPosts() -该方法用于处理AJAX请求。
从GET请求中读取'start' ,并分配给$start 。根据$start 和$rowperpage ,从posts 表中获取记录。
在获取的记录上循环,创建布局,并将其分配给$html 变量。
将$html 赋值给$data['html'] 。
以JSON格式返回$data 数组。
完成的代码
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Posts;
class PostsController extends Controller {
public $rowperpage = 4; // Number of rowsperpage
public function index(){
// Number of rowsperpage
$data['rowperpage'] = $this->rowperpage;
// Total number of records
$data['totalrecords'] = Posts::select('*')->count();
// Fetch 4 records
$data['posts'] = Posts::select('*')
->skip(0)
->take($this->rowperpage)
->get();
// Load index view
return view('index',$data);
}
// Fetch records
public function getPosts(Request $request){
$start = $request->get("start");
// Fetch records
$records = Posts::select('*')
->skip($start)
->take($this->rowperpage)
->get();
$html = "";
foreach($records as $record){
$id = $record['id'];
$title = $record['title'];
$description = $record['description'];
$link = $record['link'];
$html .= '<div class="card w-75 post">
<div class="card-body">
<h5 class="card-title">'.$title.'</h5>
<p class="card-text">'.$description.'</p>
<a href="'.$link.'" target="_blank" class="btn btn-primary">Read More</a>
</div>
</div>';
}
$data['html'] = $html;
return response()->json($data);
}
}
6.查 看
在resources/views/ 文件夹中创建index.blade.php 文件。
在$posts 数组上循环并创建布局。
创建3个隐藏字段 -
- start -存储当前行的位置
- rowperpage -存储一次要获取的行数
- totalrecords -存储记录的总数
脚本 -
创建2个函数 -
- checkWindowSize() -使用这个函数来检查屏幕是否过大或页面没有足够的内容滚动。如果条件为真,则通过调用
fetchData()函数获取新的记录。 - fetchData() -从隐藏字段读取数值。如果
start<=allcount,获取新的记录。
发送AJAX请求到route('getPosts') ,发送start 作为数据,设置dataType为'json',并在成功回调时将新获取的数据response.html 附加在最后一个<div class='post '> 。再次通过调用checkWindowSize() ,检查窗口大小。
scroll 事件 - 检查滚动是否到达页面底部。如果达到,则调用 。fetchData()
对于手机定义touchmove 事件来检测滚动。
完成的代码
<!DOCTYPE html>
<html>
<head>
<title>How to Load content on page scroll in Laravel 8</title>
<!-- Meta -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css">
<style type="text/css">
.card{
margin: 0 auto;
margin-top: 35px;
}
</style>
</head>
<body>
<div class='container'>
@foreach($posts as $post)
@php
$id = $post['id'];
$title = $post['title'];
$description = $post['description'];
$link = $post['link'];
@endphp
<div class="card w-75 post">
<div class="card-body">
<h5 class="card-title">{{ $title }}</h5>
<p class="card-text">{{ $description }}</p>
<a href="{{ $link }}" target="_blank" class="btn btn-primary">Read More</a>
</div>
</div>
@endforeach
<input type="hidden" id="start" value="0">
<input type="hidden" id="rowperpage" value="{{ $rowperpage }}">
<input type="hidden" id="totalrecords" value="{{ $totalrecords; }}">
</div>
<!-- Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript">
checkWindowSize();
// Check if the page has enough content or not. If not then fetch records
function checkWindowSize(){
if($(window).height() >= $(document).height()){
// Fetch records
fetchData();
}
}
// Fetch records
function fetchData(){
var start = Number($('#start').val());
var allcount = Number($('#totalrecords').val());
var rowperpage = Number($('#rowperpage').val());
start = start + rowperpage;
if(start <= allcount){
$('#start').val(start);
$.ajax({
url:"{{route('getPosts')}}",
data: {start:start},
dataType: 'json',
success: function(response){
// Add
$(".post:last").after(response.html).show().fadeIn("slow");
// Check if the page has enough content or not. If not then fetch records
checkWindowSize();
}
});
}
}
$(document).on('touchmove', onScroll); // for mobile
function onScroll(){
if($(window).scrollTop() > $(document).height() - $(window).height()-100) {
fetchData();
}
}
$(window).scroll(function(){
var position = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
if( position == bottom ){
fetchData();
}
});
</script>
</body>
</html>
7.演 示
8.总 结
即使页面没有足够的内容在首次加载时滚动,该代码也能发挥作用。