如何在Laravel 8的页面滚动中加载内容

163 阅读2分钟

通过无限的页面滚动,新的内容在滚动页面时动态地加载。

它是用户友好的,并提高了页面速度。

在本教程中,我展示了如何在Laravel 8项目中使用jQuery AJAX在页面滚动中加载MySQL数据库内容。

How to Load content on page scroll in Laravel 8

演示


内容

  1. 数据库配置
  2. 创建表
  3. 模型
  4. 路线
  5. 控制器
  6. 查看
  7. 演示
  8. 结语

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个隐藏字段 -

  1. start -存储当前行的位置
  2. rowperpage -存储一次要获取的行数
  3. 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.总 结

即使页面没有足够的内容在首次加载时滚动,该代码也能发挥作用。