共计 9479 个字符,预计需要花费 24 分钟才能阅读完成。
前面已经完成一个简单的商品中心服务提供商品列表接口,也用selenium捞了点数据,现在得折腾个展示页面,这个前端展示就直接html5+bootstrap+jquery来搞了,没有其他后端服务~
CV个导航栏
上bootstrap示例中cv一个nav下来改改
<nav class="navbar navbar-expand-lg navbar-light bg-light rounded">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExample09">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled">Disabled</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
<form class="form-inline my-2 my-md-0">
<input class="form-control" type="text" placeholder="Search" aria-label="Search">
</form>
</div>
</nav>
增加个logo
随便用一个吧,就用grafana得图标整整
<a class="navbar-brand" href="#">
<img src="https://grafana.com/static/img/menu/grafana2.svg" width="" height="" alt=""
class="logo-img">
</a>
增加点效果,让logo图标选转起来,可以使用keyframes 来配置动画效果
<style>
.rounded-circle {
width: 30px;
height: 30px;
}
.rotate {
animation: rotation 3s infinite linear;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
</style>
最后nav中得图标img标签用上这个class即可
<a class="navbar-brand" href="#">
<img src="https://grafana.com/static/img/menu/grafana2.svg" width="" height="" alt=""
class="logo-img rounded-circle rotate">
</a>
固定导航栏
如果要让导航栏固定在头部,可以给导航加个stick-top
类属性
<nav class="navbar sticky-top navbar-expand-lg navbar-light bg-light">
</nav>
搜索框调整
虽然搜索服务还没整,但是也先调整下样式,后面服务上了再细细搞
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-dark my-2 my-sm-0" type="submit">Search</button>
</form>
填充商品列表
创建个id为product-list
的div,后面jq就根据这个id来定位更新元素
<div class="row" id="product-list">
</div>
用ajax获取后端数据,然后拼接html元素
var products_center_addr = "http://products-center.xadocker.cn"
function renderProductList(page) {
$.getJSON(products_center_addr + '/products?per_page=24&page=' + page, function (data) {
var products = data.products;
totalPages = data.total_pages;
var html = '';
for (var i = 0; i < products.length; i++) {
var product = products[i];
html += '<div class="card col-2" >';
html += '<img class="card-img-top" src="' + product.img + '" alt="' + product.title + '" title="' + product.title + '">';
html += '<div class="card-body p-0">';
html += '<div class="row align-items-end">'
html += '<div class="col text-left">\n' +
' <span style="font-size: 15px; color: red;">¥' + product.price + '</span></div>';
html += '<h6 class="card-title" title="' + product.title + '">' + product.title + '</h6>';
html += '<div class="card-text" title="' + product.description + '"><span style="font-size: 15px; color: gray;">' + product.description + '</span></div>';
// html += '<div class="col text-right">\n' +
// ' <span style="font-size: 10px; color: gray;">库存:' + 10 + '</span></div>';
html += '</div>'
html += '</div></div>';
}
$('#product-list').html(html);
});
}
整个分页组件
在product-list的div下创个nav用来放置分页组件
<nav>
<ul class="pagination" id="pagination">
</ul>
</nav>
jq中处理分页信息方法
var currentPage = 1;
var totalPages = 1;
var viewPagesNum = 5;
function renderPagination() {
// 显示当前页码前后两个页码
var startPage = Math.max(1, currentPage - Math.floor(viewPagesNum / 2));
var endPage = Math.min(totalPages, currentPage + Math.floor(viewPagesNum / 2));
if (startPage == 1) {
endPage = viewPagesNum
}
if (endPage == totalPages) {
startPage = totalPages - viewPagesNum + 1
}
var html = '';
// 添加“上一页”按钮
html += '<li class="page-item' + (currentPage == 1 ? ' disabled' : '') + '"><a class="page-link" href="#" onclick="gotoPage(' + (currentPage - 1) + ')">上一页</a></li>';
// 添加页码按钮
for (var i = startPage; i <= endPage; i++) {
html += '<li class="page-item' + (i == currentPage ? ' active' : '') + '"><a class="page-link" href="#" onclick="gotoPage(' + i + ')">' + i + '</a></li>';
}
// 添加“下一页”按钮
html += '<li class="page-item' + (currentPage == totalPages ? ' disabled' : '') + '"><a class="page-link" href="#" onclick="gotoPage(' + (currentPage + 1) + ')">下一页</a></li>';
$('#pagination').html(html);
}
效果
效果图
最后效果如下,修修整整,浪费时间,没想到CV工程师不是CV这么简单。。。就先这样吧,反正博主只要能展示后端数据就好了
最后的代码
<!DOCTYPE html>
<html>
<head>
<title>DuckDuckRunning</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/bootstrap.min.css">
<script src="js/jquery.min.js"></script>
<script src="js/popper.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<style>
body {
background-color: #f5f5f5;
}
.row {
margin: 0px;
}
.card {
margin: 0px;
border: none;
margin-top: 10px;
margin-bottom: 10px;
padding-top: 10px;
padding-left: 5px;
padding-right: 5px;
padding-bottom: 10px;
}
.card:hover {
z-index: 1;
border: 1px solid #c9c9c9; /* 设置边框为浅灰色 */
box-shadow: 0 0 1px 1px #f8f8f8;
}
.price-text {
font-size: 15px;
color: red;
margin-bottom: 0;
}
.stock-text {
margin-left: 5px;
margin-bottom: 0;
font-size: 10px;
color: grey;
}
.card-title, .card-text {
margin: 0;
padding-left: 10px;
margin-top: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.navbar-brand {
height: 100%;
display: flex;
align-items: center;
}
.rounded-circle {
width: 30px;
height: 30px;
}
.rotate {
animation: rotation 3s infinite linear;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
.red-line {
height: 2px;
background-color: red;
}
.navbar {
border-bottom: 2px solid red;
}
.navbar-nav .nav-item.active .nav-link {
/*background-color: red;*/
color: red;
}
.navbar-nav li a {
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<nav class="navbar sticky-top navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">
<img src="https://grafana.com/static/img/menu/grafana2.svg" width="" height="" alt=""
class="logo-img rounded-circle rotate">
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">秒杀</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown"
aria-expanded="false">
类别
</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">电脑</a>
<a class="dropdown-item" href="#">手机</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">相机</a>
</div>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-dark my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
<div class="red-line"></div>
</nav>
<div class="row" id="product-list">
</div>
<nav>
<ul class="pagination" id="pagination">
</ul>
</nav>
</div>
<script>
var currentPage = 1;
var totalPages = 1;
var viewPagesNum = 5;
var products_center_addr = "http://products-center.xadocker.cn"
function renderProductList(page) {
$.getJSON(products_center_addr + '/products?per_page=24&page=' + page, function (data) {
var products = data.products;
totalPages = data.total_pages;
var html = '';
for (var i = 0; i < products.length; i++) {
var product = products[i];
html += '<div class="card col-2" >';
html += '<img class="card-img-top" src="' + product.img + '" alt="' + product.title + '" title="' + product.title + '">';
html += '<div class="card-body p-0">';
html += '<div class="row align-items-end">'
html += '<div class="col text-left">\n' +
' <span style="font-size: 15px; color: red;">¥' + product.price + '</span></div>';
html += '<h6 class="card-title" title="' + product.title + '">' + product.title + '</h6>';
html += '<div class="card-text" title="' + product.description + '"><span style="font-size: 15px; color: gray;">' + product.description + '</span></div>';
// html += '<div class="col text-right">\n' +
// ' <span style="font-size: 10px; color: gray;">库存:' + 10 + '</span></div>';
html += '</div>'
html += '</div></div>';
}
$('#product-list').html(html);
renderPagination();
});
}
function renderPagination() {
// 显示当前页码前后两个页码
var startPage = Math.max(1, currentPage - Math.floor(viewPagesNum / 2));
var endPage = Math.min(totalPages, currentPage + Math.floor(viewPagesNum / 2));
if (startPage == 1) {
endPage = viewPagesNum
}
if (endPage == totalPages) {
startPage = totalPages - viewPagesNum + 1
}
var html = '';
// 添加“上一页”按钮
html += '<li class="page-item' + (currentPage == 1 ? ' disabled' : '') + '"><a class="page-link" href="#" onclick="gotoPage(' + (currentPage - 1) + ')">上一页</a></li>';
// 添加页码按钮
for (var i = startPage; i <= endPage; i++) {
html += '<li class="page-item' + (i == currentPage ? ' active' : '') + '"><a class="page-link" href="#" onclick="gotoPage(' + i + ')">' + i + '</a></li>';
}
// 添加“下一页”按钮
html += '<li class="page-item' + (currentPage == totalPages ? ' disabled' : '') + '"><a class="page-link" href="#" onclick="gotoPage(' + (currentPage + 1) + ')">下一页</a></li>';
$('#pagination').html(html);
}
function gotoPage(page) {
if (page < 1 || page > totalPages) {
return;
}
currentPage = page;
renderProductList(page);
}
$(document).ready(function () {
renderProductList(1);
});
</script>
</body>
</html>
部署文件
dockerfile
FROM openresty/openresty:1.21.4.1-buster
WORKDIR /app
COPY . .
COPY nginx.conf /etc/nginx/conf.d/default.conf
RUN rm -f nginx.conf Dockerfile
# 暴露端口
EXPOSE 80
nginx.conf
server {
listen 80;
server_name mall.xadocker.cn; # 修改为你的域名
# 设置网站根目录
root /app;
# 设置默认页面
index index.html;
# 静态资源缓存设置
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000";
access_log off;
}
# 处理HTML页面请求
location / {
try_files $uri $uri/ /index.html;
}
# 处理404错误
error_page 404 /404.html;
location = /404.html {
internal;
}
}
正文完