如何用ajax显示页面?

Kar*_*ary 6 php ajax jquery mysqli

我有一个正常工作的分页,即使我已经添加了一个过滤器来分页同一页面上的更多行,也就是说通过过滤器我可以显示10行或50行.

我在代码中遇到的一个小缺陷就是页面被重新加载,改变了显示的行数,并且在分页的按钮中也是如此.

这是我的代码,一切都在同一页面index2.php上工作.

<div id="wrapper">
    <div class="container">
        <div id="news-header" class="bootgrid-header container-fluid">
            <div class="row">
                <div class="col-sm-12 actionBar">
                    <div class="search-bar">
                        <input type="text" id="myInput" onkeyup="myFunction()" placeholder="What are you looking for?">
                    </div>
                    <div class="actions btn-group">
                        <?php
                            $select_quantity = '';
                            if (isset($_POST['amount_show'])) :
                                $select_quantity = $_POST['amount_show'];
                            endif;
                        ?>
                        <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
                            <select id="amount_show" name="amount_show" onchange="this.form.submit()">
                                <option value="10" <?php if ($select_quantity==10) echo "selected"; ?>>10</option>
                                <option value="25" <?php if ($select_quantity==25) echo "selected"; ?>>25</option>
                                <option value="50" <?php if ($select_quantity==50) echo "selected"; ?>>50</option>
                                <option value="100" <?php if ($select_quantity==100) echo "selected"; ?>>100</option>
                            </select>
                        </form>
                    </div>
                </div>
            </div>
        </div>
        <?php
            if (isset($_GET['page'])) :
                $page = $_GET['page'] ?: '';
            else :
                $page = 1;
            endif;

            if (isset($_POST['amount_show'])) :
                $records_by_page = $_POST['amount_show'];
            else :
                $records_by_page = 10;
            endif;

            $localization_sql = ($page-1) * $records_by_page;

            $sql = "SELECT id,title,description
                    FROM news
                    ORDER BY id DESC LIMIT $localization_sql, $records_by_page";
            $stmt = $con->prepare($sql);
            $stmt->execute();
            $stmt->store_result();
            if ($stmt->num_rows>0) :

            echo '<table id="myTable" class="table table-condensed table-hover table-striped bootgrid-table">
            <thead>
                <tr>
                    <th>Id</th>
                    <th>Title</th>
                    <th>Description</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody>';

            $stmt->bind_result($id,$title,$description);
            while ($stmt->fetch()) :
                echo '<tr>
                    <td>'.$id.'</td>
                    <td>'.$title.'</td>
                    <td>'.$description.'</td>
                    <td>Edit</td>
                </tr>';
            endwhile;
            echo '</tbody>';
            echo '</table>';
            $stmt->close();


            $sql = "SELECT * FROM news";
            $stmt = $con->prepare($sql);
            $stmt->execute();
            $stmt->store_result();

            $BD_records = $stmt->num_rows;
            $stmt->close();
            $con->close();

            $total_page = ceil($BD_records / $records_by_page);
            $prev = $page - 1;
            $next = $page + 1;
            echo '<div class=pagination>
            <ul class="pagination">';
            if ($prev > 0) :
                echo "<li><a href='index2.php?page=1'><i class='icon-angle-double-arrow'></i></a></li>";
                echo "<li><a href='index2.php?page=$prev'><i class='icon-angle-left'></i></a></li>";
            endif;

            for ($i=1; $i<=$total_page; $i++) :
                if ($page==$i) :
                    echo "<li><a class=active>". $page . "</a></li>";
                else :
                    echo "<li><a href='index2.php?page=$i'>$i</a></li>";
                endif;
            endfor;


            if ($page < $total_page ) :
                echo "<li><a href='index2.php?page=$next'><i class='icon-angle-right'></i></a></li>";
                echo "<li><a href='index2.php?page=$total_page'><i class='icon-angle-double-right'></i></a></li>";
            endif;

            echo '</ul></div>';

            else :
                $stmt->close();
            endif;

        ?>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

在网上搜索时,我发现了一个ajax代码,但是真诚地,我没有管理使用ajax或javascript/jquery代码.

您可以解释如何实现此ajax代码或如何避免重新加载页面的小缺陷.

<script type="text/javascript">
$(document).ready(function() {  
    $('.pagination li a').on('click', function(){
        /*$('.items').html('<div class="loading"><img src="images/loading.gif" width="70px" height="70px"/><br/>Loading...</div>');*/
        $('.items').html('<div class="loading">Loading...</div>');

        var page = $(this).attr('data');        
        var dataString = 'page='+page;

        $.ajax({
            type: "GET",
            url: "ajax.php",
            data: dataString,
            success: function(data) {
                $('.items').fadeIn(2000).html(data);
                $('.pagination li').removeClass('active');
                $('.pagination li a[data="'+page+'"]').parent().addClass('active');

            }
        });
        return false;
    });              
});    
</script>
Run Code Online (Sandbox Code Playgroud)

这就是我的代码的工作方式,如下图所示:

在此输入图像描述

bbe*_*enz 5

Ajax将在不重新加载页面的情况下更新页面上的信息.我们希望将数据与HTML分开,以便我们可以更改我们看到的数据.如果PHP是将数据写入HTML的工具,我们就无法做到这一点.所以我建议将index2.php分成几个文件.此示例使用JSON.

收集数据

ajax.php

<?php
$data_rows = array();

for ($i = 0; $i < 1000; $i++) {
    $data_rows[] = array(
        "id" => "id_$i",
        "title" => "title_$i",
        "description" => "description_$i",
    );
}

echo json_encode($data_rows, JSON_PRETTY_PRINT);
Run Code Online (Sandbox Code Playgroud)

这是一些垃圾数据的例子,我不知道你需要什么数据.这里重要的是创建一个所需信息的关联数组,json_encode()数组,然后echo它.重要的是,这是唯一得到回应或印刷的东西!如果您在此脚本中打印了其他任何内容,则无法使用此功能.

编辑:

ajax.php

if (isset($_GET['page'])) :
                $page = $_GET['page'] ?: '';
            else :
                $page = 1;
            endif;

            if (isset($_POST['amount_show'])) :
                $records_by_page = $_POST['amount_show'];
            else :
                $records_by_page = 10;
            endif;

$sql = "SELECT id, title, description
FROM news
ORDER BY id DESC LIMIT $localization_sql, $records_by_page";
$result = $con->query($sql);
$data_rows = array();
while ($row = $result->fetch_assoc()) {
    $data_rows = $row;
}

echo json_encode($data_rows, JSON_PRETTY_PRINT);
Run Code Online (Sandbox Code Playgroud)

您的原始代码包含此mysqli连接,这是我无法访问的数据,因此我无法测试此脚本的功效.但是,这应该显示您询问的所有数据.

使用jQuery的Ajax

的script.js

$(document).ready(function() {  
 $.ajax({
            type: "GET",
            url: "ajax.php",
            dataType: "json",
            success: function(data) {
                tableRows = '';
                for (let i = 0; i < data.length; i++) {
                    tableRows += `
                    <tr>
                        <td>${data[i].id}</td>
                        <td>${data[i].title}</td>
                        <td>${data[i].description}</td>
                        <td>Edit<td>
                    </tr>`;
                }
                $("#tbody-insert").html(tableRows);
            }
    });              
}); 
Run Code Online (Sandbox Code Playgroud)

将ajax调用的url参数设置为传递数据的php文件的名称.在我使用JSON的示例中,设置很重要dataType: "json".jQuery会自动为你解析这个.你可以在success参数中看到,data是我们创建的php数组的名称.我使用一个简单的for循环来创建一堆表行,然后将它们插入到我标记过的表体中id="tbody-insert".

提供数据

的index.html

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<table id="myTable" class="table table-condensed table-hover table-striped bootgrid-table">
    <thead>
        <tr>
            <th>Id</th>
            <th>Title</th>
            <th>Description</th>
            <th>Action</th>
        </tr>
    </thead>
    <tbody id="tbody-insert">

    </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

我已经从你的索引页面中取出了所有的PHP,它不是很灵活,它需要在更新信息之前重新加载整个页面.要注意的重点是脚本标记,您需要包含jQuery,并且需要包含script.js.您还需要为我们正在插入信息的表体提供一个id.您可以将ajax包装在每次要分页时调用的函数中,并查询ajax.php以查找不同的页面.我不知道你的数据结构,所以我无法继续帮助你.


msg*_*msg 2

让我们从导致页面重新加载的原因开始:默认浏览器操作。多个 html 元素会导致浏览器离开当前页面。本案中我们关心的问题是:

  • #amount_show formonchange通过以下方式发送新值的提交(函数)POST函数) 。
  • 分页器本身(带有a链接)告诉 php 脚本通过GET请求检索哪些记录。

这两个值都应该传递给 php 脚本,以便它能够返回正确的记录,否则amount即使我们选择了不同的值,该参数也将是 php 脚本中的默认值。为了能够做到这一点,我们必须将amount变量的传递更改为GET请求的传递。

另外,当改变amount值时,我们将默认为第一页,以避免重新计算页码。由于分页链接可以动态更改,因此我不会在 javascript 中处理它们,而是在 php 中处理,因为我们已经有了模板和计算。这将使事情更容易改变。

我们先来处理 javascript:

$(document).ready(function() {
    // When we change the value of the select...
    //     evt contains the information about the event: 
    //         element receiving the action, the action itself, etc.

    $('#amount_show').change(function(evt) {
      // Cancel the default browser action
      evt.preventDefault()
      // Get the target url of the form (our php script)
      url = $(this).parent().attr('action')
      // Call the funtion that will be doing the request
      ajaxLoad(url)
    });

    // When we click a pagination link... (Explanation below)
    $('.items').on('click', '.pagination li a', function(evt) {
      evt.preventDefault()
      url = $(this).attr('href')
      ajaxLoad(url)
    });

    // Do the actual request
    function ajaxLoad(url) {
      // How many records do we want to show ?
      query_params = {
        amount_show: $('#amount_show').val()
      };
      // Show an indication that we are working
      $('.items').html('<div class="loading">Loading...</div>')
      $.ajax({
        type: "GET",
        url: url, // Call php, it will default to page 1 if there's no parameter set
        // When calling a link with a page parameter this will be smart
        // enough to append the variable to the query string correctly
        data: $.param(query_params),
        // Handle the data return. In a perfect world, this is always successful
        success: function(data) {
          // Insert the data in the document.
          $('.items').fadeOut('1000', function() { $(this).html(data) }).fadeIn('1000')
        }
      });
    }
  });
Run Code Online (Sandbox Code Playgroud)

该行将委托事件侦听器$('.items').on('click', '.pagination li a', function(evt) {附加到将响应接收到的事件的元素。这样做而不是直接附加到元素本身的原因有两个:.itemsclick.pagination li a

  • 减少我们必须循环并附加侦听器的元素数量。
  • 处理元素的动态插入。切换内容时,我们将从文档中删除元素及其侦听器。我们必须在每次页面加载时再次附加它们,否则如果没有附加侦听器,它们将返回到默认操作。但由于这个元素不会改变,我们就不必这样做。

现在来说说 php。由于您对使用单个文件感兴趣,因此我将移动一些内容,但它(大部分)将是您现在拥有的。
注意:我可能误解了您将所有内容都放在一个页面中的意思。如果这是您从主索引中包含的部分模板,则必须更改表单的链接目标和操作以指向它,调整一些 javascript 选择器,并且您可以跳过整个 ajax 请求检查。主要变化:

  • 删除您的onchange函数调用。
  • 将参数更改POSTGET参数。
  • 添加一个.items span来插入元素,因为它不存在。
  • X-Requested-With使用header确定页面加载是 ajax 加载还是常规加载。另一种方法是返回完整的响应并使用 jQuery 对其进行过滤。

    <?php
        if (isset($_GET['page'])) :
            $page = $_GET['page'] ?: '';
        else :
            $page = 1;
        endif;
    
        if (isset($_GET['amount_show'])) :
            $records_by_page = $_GET['amount_show'];
        else :
            $records_by_page = 10;
        endif;
    
        $localization_sql = ($page-1) * $records_by_page;
    
        $sql = "SELECT id,title,description
                FROM news
                ORDER BY id DESC LIMIT $localization_sql, $records_by_page";
        $stmt = $con->prepare($sql);
        $stmt->execute();
        $stmt->store_result();
    
        if ($stmt->num_rows>0) :
    
            // Start capturing the output
            ob_start();     
        ?>
        <table id="myTable" class="table table-condensed table-hover table-striped bootgrid-table">
            <thead>
                <tr>
                    <th>Id</th>
                    <th>Title</th>
                    <th>Description</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody>
                <?php
                    $stmt->bind_result($id,$title,$description);
                    while ($stmt->fetch()) :
                        echo '<tr>
                            <td>'.$id.'</td>
                            <td>'.$title.'</td>
                            <td>'.$description.'</td>
                            <td>Edit</td>
                        </tr>';
                    endwhile;
                    $stmt->close();
                ?>
            </tbody>
        </table>
        <div class=pagination>
        <ul class="pagination">                
                <?php            
                  // When requesting an out-of-bounds page, this won't execute resulting in 
                  // a blank page with no paginator
                  $sql = "SELECT * FROM news";
                  $stmt = $con->prepare($sql);
                  $stmt->execute();
                  $stmt->store_result();
    
                  $BD_records = $stmt->num_rows;
                  $stmt->close();
                  $con->close();
    
                  $total_page = ceil($BD_records / $records_by_page);
                  $prev = $page - 1;
                  $next = $page + 1;
    
                  if ($prev > 0) :
                      echo "<li><a href='" . $_SERVER['PHP_SELF'] . "?page=1'><i class='icon-angle-double-arrow'></i></a></li>";
                      echo "<li><a href='" . $_SERVER['PHP_SELF'] . "?page=$prev'><i class='icon-angle-left'></i></a></li>";
                  endif;
    
                  for ($i=1; $i<=$total_page; $i++) :
                      if ($page==$i) :
                          echo "<li><a class='page-link active' >". $page . "</a></li>";
                      else :
                          echo "<li><a class='page-link' href='" . $_SERVER['PHP_SELF'] . "?page=$i'>$i</a></li>";
                      endif;
                  endfor;
    
                  if ($page < $total_page ) :
                      echo "<li><a class='page-link' href='index2.php?page=$next'><i class='icon-angle-right'></i></a></li>";
                      echo "<li><a class='page-link' href='index2.php?page=$total_page'><i class='icon-angle-double-right'></i></a></li>";
                  endif;
    
                  echo '</ul></div>';
    
                  // Get the output into a variable
                  $results_table = ob_get_clean();
    
              else :
                  $results_table = "<div>No results found</div>";
                  $stmt->close();
              endif;
    
              if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) :
                  // If is an ajax request, output just the result table and exit
                  echo $results_table;
                  die;
              endif;
              // Print the whole page if its not an ajax request
          ?>
      <script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js'/>
      <script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js' />
      <link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css' type='text/css' />
      <div id='wrapper'>
        <div class='container'>
          <div id='news-header' class='bootgrid-header container-fluid'>
            <div class='row'>
              <div class='col-sm-12 actionBar'>
                <div class='search-bar'>
                  <input type='text' id='myInput' placeholder='What are you looking for?'>
                </div>
                <div class='actions btn-group'>
                  <form action=<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>'>
                    <select id='amount_show' name='amount_show'>
                    </select>
                  </form>
                </div>
              </div>
            </div>
          </div>
    
          <span class='items'>
            <?php echo $results_table; ?>
          </span>
        </div>
      </div>
    
    Run Code Online (Sandbox Code Playgroud)

为了完整起见,不使用 php 分隔响应的替代方法是通过在回调中执行以下操作来使用 jQuery 过滤响应ajax success(省略淡入淡出):

results_table = $(data).find('.items').html()
$('.items').html(results_table)
Run Code Online (Sandbox Code Playgroud)

这会将服务器的响应转换为 jQuery 对象,并允许正常应用过滤功能。我们提取我们感兴趣的内容(items结果表和分页的内容),然后将其附加到items现有页面的容器中。

更新:我在这里发布了一个没有数据库相关代码的简化示例。我认为从编辑器复制和粘贴代码时会发生一些奇怪的事情。

参考