目录
本次项目为后台管理系统,在本系统内的第四个界面为窗体程序内的文章列表页面,作为首页内大分类下的小分类项目,需要和首页进行联合
文章列表的的功能介绍:
在进行本页面时,我们将进行多个功能的串联
1、进入页面
在首页进入时需要变换分类的样式,使用排他思想即可进行该项操作,而在大分类展开小分类的事件中使用基础动画效果即可
2、页面内的各种功能设计
(1)文章表格
由于数据库的调取,我们需要实时对表格进行更改,此时就要进行以下思路:
调取数据 > 渲染表格 > 用户操作数据 > 数据库接受更改,并存储 > 调取数据 >重新渲染表格
在调取接口时,使用拼接表格操作,将需要调取的数据直接进行渲染。
在调取数据库内的数据时,会同时返回数据量和多种数据,根据调用接口的不同来确定返回数据
(2)删除按钮
需注意每条数据在数据库和网页都具有一个唯一的标识符,该行的重点在于点击按钮时告知数据库删除的标识符,并返回数据。在后端数据库更改完数据后我们再次对表格进行渲染,以调取删除后的数据来完成该次操作。
在编写代码时,我们需注意前端注重的交互体验,即人机交互体验,类似于删除时提醒用户是否删除,告知删除是否完成等操作。
即注重用户体验也是前端的主要目标之一。
(3)编辑按钮
在要求中我们确定编辑按钮作为跳转按钮存在,将跳转到发表文章大分类内进行编辑,但是需要注意的是我们再跳转该网页的同时要附带我们点击编辑时所点击的编辑选项的唯一标识符,作为下个页面内渲染数据的支持
(4)发表文章按钮
发表文章按钮同理但是不做携带唯一标识符的处理
(5)所有分类下拉框
该下拉框会有专门的接口为我们进行调取来选择本身有的分类选项和后续我们添加的分类选项
(6)关键字检索
该处不做交互设计,我们只需要在其中写入数值让其他操作能读取到其中的内容并接收即可
(7)所有状态下拉框
该处也不做特殊处理,需要注意某些类似于布尔值一般的对错二选一,我们一般不使用接口进行特殊渲染,而是对其进行选择操作,即返回他们的值然后接收
(8)筛选按钮
该处按钮的设计将会返回三个值,分别是关键字检索,所有分类下拉框,所有状态下拉框
即我们的接口将调用多项值,在代码设计中我们将会获取其中的值并返回数据库,然后接收数据库修改后返回的值。
(9)页面底部的页码跳转
该处我们需获取表格后对总页数进行显示(后端会返还页数和每页条目消息),获取并写入跳转页等操作
当我们对于这些基础功能进行一些简单的说明和归类后我们就可以开始进行该页面的项目编写
一、网页设计
二、HTML代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文章列表</title>
<link rel="stylesheet" href="./CSS/reset.css">
<link rel="stylesheet" href="./CSS/article.css">
</head>
<body>
<!-- 在该处代码完成iframe中的头部和选择区域 -->
<div class="header" id="header">文章列表</div>
<div class="main" id="main">
<input type="text" class="maintext" id="maintext" placeholder="请输入关键字···">
<select name="" id="mainselect1" value="">
<option value="" selected>所有分类</option>
</select>
<select name="" id="mainselect2" value="">
<option value="" selected>所有状态</option>
<option value="已发布">已发布</option>
<option value="草稿">草稿</option>
</select>
<button class="mainbtn" id="mainbtn">筛选</button>
<button class="mainpublish" id="mainpublish">发表文章</button>
</div>
<!-- 此处是表格渲染的区域 -->
<div class="btm">
<table>
<thead>
<th id="title">标题</th>
<th id="author">作者</th>
<th id="classify">分类</th>
<th id="submission">提交时间</th>
<th id="state">状态</th>
<th id="operate">操作</th>
</thead>
<tbody>
</tbody>
</table>
<!-- 该处是页码中跳转按钮和页码变化的按钮 -->
<div class="foot">
<span class="btmup" id="btmup">上一页</span>
<input type="text" class="btmtext" id="btmtext">
<span style="background-color: white;" id="btmt"></span>
<span class="btmload" id="btmload">跳转</span>
<span class="btmdown" id="btmdown">下一页</span>
</div>
</div>
</body>
<script src="./JS/jquery.min.js"></script>
<script src="./JS/move.js"></script>
<script src="./JS/article.js"></script>
</html>
三、css代码
css
button{
cursor: pointer;
}
body
{
font-size: 16px;
background-color: #f2f3f5;
}
.header
{
width: 88vw;
height: 4vh;
background-color: #fbfbfb;
margin: 3vh auto;
margin-bottom: 0px;
line-height: 4vh;
border: 1px solid #a2a2a3;
padding-left: 2vw;
}
.main
{
color: #5b5b5b;
font-size: 13px;
width: 88vw;
background-color: #ffffff;
margin: 0vh auto;
border: 1px solid #a2a2a3;
border-top: none;
padding: 2vh 1vw;
position: relative;
}
.maintext
{
padding-left: 5px;
height: 20px;
width: 150px;
outline: none;
margin: 0px 10px;
}
#mainselect1 ,
#mainselect2
{
height: 24px;
width: 100px;
padding-left: 5px;
margin-right: 10px;
cursor: pointer;
}
.mainbtn
{
background-color: white;
border: 1px solid #5b5b5b;
height: 24px;
width: 50px;
border-radius: 3px;
}
.mainpublish
{
background-color: #5cb85c;
border: none;
height: 24px;
width: 70px;
color: white;
border-radius: 3px;
position: absolute;
right: 20px;
}
.btm
{ height: 75vh;
color: #5b5b5b;
font-size: 13px;
width: 88vw;
background-color: #ffffff;
margin: 3vh auto;
margin-top: 0px;
border: 1px solid #a2a2a3;
border-top: none;
padding: 2vh 1vw;
position: relative;
}
table
{
border: 1px solid #a2a2a3;
border-collapse: collapse;
font-size: 14px;
}
th ,td{
border: 1px solid #a2a2a3;
height: 40px;
}
td
{
padding:0px 10px;
}
#title
{
width: 50vw;
}
#author
{
width: 8vw;
}
#classify
{
width: 12vw;
}
#submission
{
width: 10vw;
}
#state
{
width: 10vw;
}
#operate
{
width: 12vw;
}
.btm span{
padding: 10px 20px;
background-color: #c5c5c5;
border-radius: 10px;
cursor: pointer;
}
.btmtext{
min-width: 20px;
max-width: 50px;
/* padding-left: 5px; */
text-align: center;
outline: none;
height: 30px;
}
.foot
{
position: absolute;
bottom: 20px;
left: 50%;
margin-left: -140px;
}
.btn1
{
background-color: #ffcb8b;
border: 1px solid #3a3a3a;
width: 50px;
height: 25px;
color: black;
font-size: 12px;
border-radius: 5px;
}
.btn2
{
background-color: #d9534f;
border: 1px solid #3a3a3a;
width: 50px;
height: 25px;
color: white;
border-radius: 5px;
font-size: 12px;
}
四、js代码
javascript
// 定义文章的跳转页面初始在第一页
var page = 1
// 定义后端数据库返回的总页数的变量
var totalpage
// 定义状态的值
var state = ""
// 定义分类的值
var type = ""
// 定义文章列表内的唯一标识符的id值被赋值的对象
var index
// 定义关键字检索的值
var key = ""
//获取文章列表分类的具体数据并对其进行渲染
getlist()
//获取文章列表表格数据并渲染
getTable()
//上一页
$("#btmup").on("click", function () {
//点击时值是否小于正常页数的最小值
if (page > 1) {
// 如果不小于则在需要减少时进行自减
page--
//并重新将赋值给page,同时进行表格的再次渲染,使之前写入的page值发生改变已做到改变渲染的页面
getTable()
} else {
//如果是小于最小值则提示用户已经是首页
alert("已经是首页")
}
})
//下一页
$("#btmdown").on("click", function () {
//点击时值是否大于正常页数的最大值
if (page < totalpage) {
//如果不大于则进行自增
page++
//并重新将赋值给page,同时进行表格的再次渲染,使之前写入的page值发生改变已做到改变渲染的页面
getTable()
}
else {
//如果大于最大值则提示用户已经是尾页
alert("已经是尾页")
}
})
//跳转
$("#btmload").on("click", function () {
//获取到输入的值,并对其中可能出现的浮点数进行向下取整处理
//同时对其进行使用变量代替
var text = Math.floor($("#btmtext").val())
// 当变量在我们后端数据库返回的正常页数内时
if (text <= totalpage && text > 0) {
// 我们将需要跳转的数赋值给page
page = text;
// 同时进行表格的再次渲染,使之前写入的page值发生改变已做到改变渲染的页面
getTable()
}
// 如果我们获取到的值已经超过了正常页数
else {
//则提示用户输入正确的页数
alert("请输入正确的页数")
//同时对我们的输入框进行清空并返回第一页,且再次对表格进行渲染来完成刷新
$("#btmtext").val("")
$("#btmtext").val(1)
getTable()
}
})
//删除按钮事件
//通过事件委托的形式,在点击时通过父元素来获取到我们点击的元素
$("tbody").on("click", "#btn2", function () {
// 定义一个选择提示框,提醒用户是否确定删除
var r = confirm("确定要删除吗")
// 在此我们获取到该删除按钮父级元素th的父级元素tr,即该行的唯一标识符
index = $(this).parents().parents().attr("index")
// 如果我们获取到选择提示框的值是true
if (r) {
// 开始调用接口
$.ajax({
// 接口地址
url: "http://localhost:8080/api/v1/admin/article/delete",
// 请求方式
type: "post",
// 请求头
headers: {
"Authorization": sessionStorage.getItem("token")
},
// 请求体
data: {
id: index
},
// 请求成功
success(res) {
//获取msg的值来判断后端数据库返回值的值是否为我们需要的值
if (res.msg == "文章删除成功") {
// 重新获取表格数据并渲染
getTable()
// 并对用户提示该处文章删除成功
alert("已删除该文章")
}
},
// 请求失败
error(err) {
console.log(err)
}
})
}
})
//筛选按钮点击事件
$("#mainbtn").on("click", function () {
//该处重新对page值进行重置,防止我们再进行筛选时,我们之前的page值还在
page = 1
// 调取接口
$.ajax({
// 接口地址
// 需注意此时我们的接口返回的值将会对关键字检索,分类选择,状态选择,页数选择,每页显示条数进行筛选
url: "http://localhost:8080/api/v1/admin/article/query?key=" + key + "&state=" + state + "&type=" + type + "&page=" + page + "&perpage=10",
//请求方式
type: "get",
// 请求头
headers: {
"Authorization": sessionStorage.getItem("token")
},
// 请求成功
success(res) {
// 我们的的变量将获取到我们在筛选页面的筛选条件的具体值
state = $("#mainselect2").val()
type = $("#mainselect1").val()
key = $("#maintext").val()
// 同时对表格进行重新渲染
getTable()
},
// 请求失败
error(err) {
// 返回错误
console.log(err);
}
})
})
//编辑跳转到发表文章页面
//注意我们的表格内容是使用渲染的方式进行的,我们通过点击事件来获取到我们点击的元素,
$("tbody").on("click", "#btn1", function () {
//获取到我们点击的元素,即该行的唯一标识符
index = $(this).parents().parents().attr("index")
//并将该行的唯一标识符赋值给index,且在跳转时将该标识符进行携带,以实现跳转至编辑页面时我们对于数据的渲染的准确性
//在对跳转时我吗们使用location.href来进行跳转,并直接将变量拼接到跳转地址中
location.href = `./publish.html?id=` + index
// console.log(`./publish.html?id=` + index);
})
//发表文章按钮的点击事件
$("#mainpublish").on("click", function () {
// 由于不需要携带数据,所以直接跳转即可
location.href = `./publish.html`
})
//表格的渲染,由于需要不断的调用,并且需要在页面开始的时候进行一次渲染,所以将其写成一个封装函数
function getTable() {
// 调取接口
$.ajax({
// 接口地址
// 需注意此时我们的接口返回的值将会对关键字检索,分类选择,状态选择,页数选择,每页显示条数进行筛选
url: "http://localhost:8080/api/v1/admin/article/query?key=" + key + "&state=" + state + "&type=" + type + "&page=" + page + "&perpage=10",
// 请求方式
type: "get",
// 请求头
headers: {
"Authorization": sessionStorage.getItem("token")
},
// 请求成功
success(res) {
// 此处编写代码时可在控制台获取到所需的数据,但一般省略
// console.log(res)
// 在msg中获取到数据获取成功时
if (res.msg == "数据获取成功") {
// 先对总页数进行获取并渲染
$("#btmt").html("共 " + res.data.totalPage + " 页")
// 声明一个需要进行拼接前的空字符串,且注意带变量为局部变量
var str = ""
totalpage = res.data.totalPage
// 将获取到的对象组成的伪数组进行声明变量并赋值
var arr = res.data.data
//遍历该数组
for (var item of arr) {
//在获取到值之后将其进行拼接,并对其加入一个可以在全局读取的唯一标识符
//注意此处我们使用的是item.id,即我们获取到的对象中的id值,该值在后端数据库中为唯一的数据标识符
str += `<tr index=${item.id}>
<td>${item.title}</td>
<td style="text-align: center;">${item.author}</td>
<td style="text-align: center;">${item.category}</td>
<td style="text-align: center;">${item.date}</td>
<td style="text-align: center;">${item.state}</td>
<td style="text-align: center;">
<button class="btn1" id="btn1">编辑</button>
<button class="btn2" id="btn2">删除</button>
</td>
</tr>
`
// 同时写入两个按钮,一个为编辑,一个为删除
}
// 将拼接后的字符串写入表格中
$("tbody").html(str)
//表格的样式,即对表格各行换色
$("tr:odd").css("background", "#f5f5f5")
}
},
// 请求失败
error(err) {
// 返回错误
console.log(err);
}
})
//渲染表格后写入当前page值代表的页数
$("#btmtext").val(page)
}
//分类的提取,由于需要不断的调用,并且需要在页面开始的时候进行一次渲染,所以将其写成一个封装函数
function getlist() {
// 调用接口
$.ajax({
// 接口地址
url: "http://localhost:8080/api/v1/admin/category/list",
// 请求方式
type: "get",
// 请求头
headers: {
"Authorization": sessionStorage.getItem("token")
},
// 请求成功
success(res) {
// console.log(res)
if (res.msg == "获取成功") {
// 声明一个变量进行拼接
var str = ""
var arr = res.data
//先拼接一个默认选中且不再数据库内的全选选项
str += `
<option value="" selected > 所有分类</option >
`
for (var item of arr) {
//遍历并拼接分类数据
str += `
<option value="${item.id}">${item.name}</option>
`
}
//将其写入下拉框中
$("#mainselect1").html(str)
}
},
// 请求失败
error(err) {
// 返回错误
console.log(err);
}
})
}