如何用ajax显示页面?
Posted
技术标签:
【中文标题】如何用ajax显示页面?【英文标题】:How to display the page with ajax? 【发布时间】:2019-03-15 19:19:00 【问题描述】:即使我添加了一个过滤器来对同一页面上的更多行进行分页,我的分页也能正常工作,也就是说通过过滤器我可以显示 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>
在网上搜索时,我发现了一个 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" /><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>
这就是我的代码的工作方式,如下图所示:
【问题讨论】:
那么你真的尝试过ajax 吗?如果有,结果如何?您是如何尝试解决您遇到的任何问题的?如果您没有尝试过,那么请尝试一下。您应该在发布问题之前尝试解决您的任务/问题。 @PatrickQ 你好朋友......我已经按照我找到的示例进行操作,显然在 ajax 中正确添加了所有内容,但我很抱歉朋友,但我不知道我应该删除哪些代码文件 index2.php 添加到文件 ajax.php :( 如果我问错了,请原谅我,我只是原生使用 PHP,我不完全了解 ajax 的使用 :( 【参考方案1】: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);
这是一些垃圾数据的例子,我不知道你需要什么数据。这里重要的是创建一个包含您想要的所有信息的关联数组,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);
您的原始代码包含此 mysqli 连接,这是我无权访问的数据,因此我无法测试此脚本的功效。但是,这应该会显示您询问的所有数据。
Ajax 与 jQuery
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);
);
);
将 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>
我已经从您的索引页面中删除了所有 PHP,它不是很灵活,并且需要在更新信息之前重新加载整个页面。需要注意的重点是脚本标签,您需要包含 jQuery 并且需要包含 script.js。您还需要有一个我们要插入信息的表体的 id。您可以将您的 ajax 包装在一个函数中,该函数在您每次想要分页时都会被调用,并为不同的页面查询 ajax.php。我不知道您的数据结构,因此无法提供更多帮助。
【讨论】:
FWIW,这个答案中的 JavaScript 是 ES6,所以如果你没有转译或支持旧版浏览器,那么字符串插值将不会产生预期的结果。 @Timpy 朋友。想要的数据都在 index2.php 文件中,也就是说,我没有使用或调用另一个 PHP 文件。分页和数据显示在文件 index2.php 中,所有内容都在该文件中。 @Timpy 很抱歉承认这一点。但我不明白,在我的代码中有通过选择选项以这种方式显示 10、25、50 和 100 行的选项,它会失去有效性......我想哭我不明白......所有 PHP 代码都传递给 ajax 文件 .php 但在 json_encode 中仅打印来自数据库的数据和其他配置作为显示更多行的选项。 @Kary 很抱歉没有更清楚。在 index2.php sn-p 的第 46 行,您正在使用以下语句查询数据库:$stmt = $con->prepare($sql);
。这就是我说的数据。我将更新我的答案以使用该数据。
@Timpy 以这种方式向我显示数据$result = $con->query($sql); $data_rows = array(); while ($row = $result->fetch_assoc()) $data_rows[] = $row;
【参考方案2】:
让我们从导致页面重新加载的原因开始:default browser actions。几个 html 元素会导致浏览器离开当前页面。在这种情况下,我们关注的是:
#amount_show
form
提交(onchange
函数)通过 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')
);
);
$('.items').on('click', '.pagination li a', function(evt)
行将delegate event listener 附加到.items
元素,该元素将响应.pagination li a
收到的click
事件。这样做而不是直接附加到元素本身的原因有两个:
现在是 php。由于您对使用单个文件感兴趣,所以我只是移动一些东西,但它(大部分)将是您现在所拥有的。注意:我可能误解了您的意思通过将所有内容放在一个页面中。如果这是您从主索引中包含的部分模板,则必须更改链接目标和操作以使表单指向它,调整一些 javascript 选择器,您可以跳过整个 ajax 请求检查。 主要变化:
删除您的onchange
函数调用。
将POST
参数更改为GET
参数。
添加.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>
为了完整起见,不使用 php 分隔响应的替代方法是通过在 ajax
success
回调中执行以下操作来使用 jQuery 过滤响应(淡入淡出省略):
results_table = $(data).find('.items').html()
$('.items').html(results_table)
这会将来自服务器的响应转换为 jQuery 对象,并允许正常应用过滤功能。我们提取我们感兴趣的内容(items
的内容:结果表和分页),然后将其附加到现有页面上的items
容器中。
更新:我发布了一个简化的示例,没有与数据库相关的代码here。我认为从/向编辑器复制和粘贴代码时发生了一些奇怪的事情。
参考文献
DOM events jQuery ajax and helper 函数 PHP output buffering Not receiving X_REQUESTED_WITH request header Fade effects in ajax callback【讨论】:
嗨@msg 不是朋友...我并不是说我只希望它在一页上,只是说明我的代码当前正在运行并且只在一个文件中工作 index2.php . 我现在测试它,它打印出这些错误:Warning: mysqli_stmt::bind_result(): Couldn't fetch mysqli_stmt in index2.php on line 54
-> $stmt->bind_result($id,$title,$description);
Warning: mysqli_stmt::fetch(): Couldn't fetch mysqli_stmt in index2.php on line 55
-> while ($stmt->fetch()) :
Warning: mysqli_stmt::close(): Couldn't fetch mysqli_stmt in index2.php on line 63
-> $stmt->close();
我不明白错误,一切似乎都很好。
朋友一个效率问题,这种方式是最好的选择还是通过json更有效?
错误不再显示。但是我没有看到它在实现的所有东西上都发生了很大变化,当点击页面上的按钮时会重新加载......我认为它会有所不同,for example
我尝试过在不使用第三方插件的情况下以原生方式完成所有事情,实际上我已经做到了,只是缺少了 ajax 的那个小细节。【参考方案3】:
如果即使是纯 html 也有点超出限制,那么开始使用 jquery 和异步调用是没有意义的。在初始代码中,您混合使用 POST 和 GET,只使用一个。
<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
//getting both - page and record_by_page from GET
$records_by_page = isset($_GET['amount_show'])?$_GET['amount_show']:10;
$page = isset($_GET['page'])?$_GET['page']:1;
//put page value into form to send it together with amount_show
?>
<form method="get" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<select id="amount_show" name="amount_show" onchange="this.form.submit()">
<option value="10" <?php if ($records_by_page==10) echo "selected"; ?>>10</option>
<option value="25" <?php if ($records_by_page==25) echo "selected"; ?>>25</option>
<option value="50" <?php if ($records_by_page==50) echo "selected"; ?>>50</option>
<option value="100" <?php if ($records_by_page==100) echo "selected"; ?>>100</option>
</select>
<input type="hidden" id="page" name="page" value="<?php echo $page; ?>"></input>
</form>
</div>
</div>
</div>
</div>
<?php
$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">';
//add amount_show to each request
if ($prev > 0) :
echo "<li><a href='pagination.php?page=1&amount_show=$records_by_page'><i class='icon-angle-double-arrow'></i></a></li>";
echo "<li><a href='pagination.php?page=$prev&amount_show=$records_by_page'><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='pagination.php?page=$i&amount_show=$records_by_page'>$i</a></li>";
endif;
endfor;
if ($page < $total_page ) :
echo "<li><a href='pagination.php?page=$next&amount_show=$records_by_page'><i class='icon-angle-right'></i></a></li>";
echo "<li><a href='pagination.php?page=$total_page&amount_show=$records_by_page'><i class='icon-angle-double-right'></i></a></li>";
endif;
echo '</ul></div>';
else :
$stmt->close();
endif;
?>
</div>
</div>
【讨论】:
以上是关于如何用ajax显示页面?的主要内容,如果未能解决你的问题,请参考以下文章
如何用ajax实现,刷新页面时,页面设置的下拉菜单(select)、raido保持不变?