当前位置: 首页 > news >正文

Ajax-day2(图书管理)-渲染列表

本篇笔记素材来自“黑马程序员”

渲染列表

  • 图书管理
  • 一、获取数据
  • 二、渲染数据
  • 完整代码


图书管理

  1. Bootstrap 框架
  2. 渲染列表(查)
  3. 新增图书(增)
  4. 删除图书(删)
  5. 编辑图书(改)

自己的图书数据:给自己起个名字,并告诉服务器,
默认会有三本书,基于这三本书做数据的增删改查。

文件夹目录:
在这里插入图片描述
index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>案例-图书管理</title><!-- 字体图标 --><link rel="stylesheet" href="https://at.alicdn.com/t/c/font_3736758_vxpb728fcyh.css"><!-- 引入bootstrap.css --><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet"><!-- 核心样式 --><link rel="stylesheet" href="./css/index.css">
</head><body><!-- 主体区域 --><div class="container"><!-- 头部标题和添加按钮 --><div class="top"><h3>图书管理</h3><button type="button" class="btn btn-primary plus-btn" data-bs-toggle="modal" data-bs-target=".add-modal"> + 添加</button></div><!-- 数据列表 --><table class="table"><thead class="table-light"><tr><th style="width: 150px;">序号</th><th>书名</th><th>作者</th><th>出版社</th><th style="width: 180px;">操作</th></tr></thead><tbody class="list"><tr><td>1</td><td>JavaScript程序设计</td><td>马特·弗里斯比</td><td>人民邮电出版社</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr></tbody></table></div><!-- 新增-弹出框 --><div class="modal fade add-modal"><!-- 中间白色区域 --><div class="modal-dialog"><div class="modal-content"><div class="modal-header top"><span>添加图书</span><button type="button" class="btn-close" aria-label="Close" data-bs-dismiss="modal"></button></div><div class="modal-body form-wrap"><!-- 新增表单 --><form class="add-form"><div class="mb-3"><label for="bookname" class="form-label">书名</label><input type="text" class="form-control bookname" placeholder="请输入书籍名称" name="bookname"></div><div class="mb-3"><label for="author" class="form-label">作者</label><input type="text" class="form-control author" placeholder="请输入作者名称" name="author"></div><div class="mb-3"><label for="publisher" class="form-label">出版社</label><input type="text" class="form-control publisher" placeholder="请输入出版社名称" name="publisher"></div></form></div><div class="modal-footer btn-group"><button type="button" class="btn btn-primary" data-bs-dismiss="modal"> 取消 </button><button type="button" class="btn btn-primary add-btn"> 保存 </button></div></div></div></div><!-- 编辑-弹出框 --><div class="modal fade edit-modal"><!-- 中间白色区域 --><div class="modal-dialog"><div class="modal-content"><div class="modal-header top"><span>编辑图书</span><button type="button" class="btn-close" aria-label="Close" data-bs-dismiss="modal"></button></div><div class="modal-body form-wrap"><!-- 编辑表单 --><form class="edit-form"><input type="hidden" class="id" name="id"><div class="mb-3"><label for="bookname" class="form-label">书名</label><input type="text" class="form-control bookname" placeholder="请输入书籍名称" name="bookname"></div><div class="mb-3"><label for="author" class="form-label">作者</label><input type="text" class="form-control author" placeholder="请输入作者名称" name="author"></div><div class="mb-3"><label for="publisher" class="form-label">出版社</label><input type="text" class="form-control publisher" placeholder="请输入出版社名称" name="publisher"></div></form></div><div class="modal-footer btn-group"><button type="button" class="btn btn-primary" data-bs-dismiss="modal"> 取消 </button><button type="button" class="btn btn-primary edit-btn"> 修改 </button></div></div></div></div><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.2.0/axios.min.js"></script><script src="./lib/form-serialize.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/js/bootstrap.min.js"></script><!-- 核心逻辑 --><script src="./js/index.js"></script>
</body></html>

index.css

/* 公共*/
html,
body {width: 100%;height: 100%;
}.container {width: 1340px;margin: 0 auto;padding-top: 60px;box-sizing: border-box;
}/* alert提示框 */
.toast {position: fixed;top: 20px;left: 50%;transform: translateX(-50%);
}.toast .toast-body {padding: 0 !important;
}.toast .alert-success {margin-bottom: 0 !important;
}/* 头部导航 */
.container .top {display: flex;justify-content: space-between;
}.container .top h3 {font-weight: 900;
}.container .top .plus-btn {background-color: #539ACB !important;color: #fff;border: none;
}/* 表格部分 */
.table {margin-top: 20px;text-align: center;font-size: 14px;
}.table-light th {background-color: #939CA7 !important;color: #ffffff;font-family: PingFangSC-Medium;font-size: 16px;text-align: center;font-weight: 500;border-right: 1px solid lightgray;
}.table-light th:last-of-type {border-right: none;
}/* 表格内容 */
.table tbody td {color: #696F77;
}.table .del {color: #E5964C;margin-right: 30px;
}.table .edit {color: #539ACB;
}.table tbody tr {height: 30px;line-height: 30px;
}.table tbody tr td:last-of-type span {cursor: pointer;
}/* 弹出层 */
.modal .top {display: flex;justify-content: center;background-color: #F0F3F7;padding: 15px 0;width: 100%;position: relative;color: #1E2023;
}/* 右上角-关闭按钮 */
.modal .btn-close {font-size: 12px;position: absolute;top: 50%;transform: translateY(-50%);right: 23px;/* 覆盖bootstrap样式 */margin: 0;padding: 0;
}/* 表单容器 */
.form-wrap {box-sizing: border-box;background-color: white;padding: 40px;
}.form-wrap .form-label {color: #696F77;
}/* 修改输入框默认占位文字webkit内核, firefox18-, firfox19+, 其他*/
.form-wrap input::-webkit-input-placeholder {color: #BFBFBF !important;font-size: 14px;
}/* 底部按钮组 */
.modal-footer{border-top: 0;
}
.btn-group {text-align: center;width: 100%;
}/* 修改bs的按钮弹性布局-改成自己设置大小 */
.btn-group,
.btn-group-vertical {display: block;
}.btn-group button {width: 120px
}.btn-group button:first-of-type {border: 1px solid #E3E3E3;background-color: #fff;color: black;margin-right: 60px;
}.btn-group button:last-of-type {background-color: #539ACB;
}.alert-success {border-color: transparent;
}.toast {border: none;
}

form-serialize.js

// get successful control from form and assemble into object
// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2// types which indicate a submit action and are not successful controls
// these will be ignored
var k_r_submitter = /^(?:submit|button|image|reset|file)$/i;// node names which could be successful controls
var k_r_success_contrls = /^(?:input|select|textarea|keygen)/i;// Matches bracket notation.
var brackets = /(\[[^\[\]]*\])/g;// serializes form fields
// @param form MUST be an HTMLForm element
// @param options is an optional argument to configure the serialization. Default output
// with no options specified is a url encoded string
//    - hash: [true | false] Configure the output type. If true, the output will
//    be a js object.
//    - serializer: [function] Optional serializer function to override the default one.
//    The function takes 3 arguments (result, key, value) and should return new result
//    hash and url encoded str serializers are provided with this module
//    - disabled: [true | false]. If true serialize disabled fields.
//    - empty: [true | false]. If true serialize empty fields
function serialize(form, options) {if (typeof options != 'object') {options = { hash: !!options };}else if (options.hash === undefined) {options.hash = true;}var result = (options.hash) ? {} : '';var serializer = options.serializer || ((options.hash) ? hash_serializer : str_serialize);var elements = form && form.elements ? form.elements : [];//Object store each radio and set if it's empty or notvar radio_store = Object.create(null);for (var i=0 ; i<elements.length ; ++i) {var element = elements[i];// ingore disabled fieldsif ((!options.disabled && element.disabled) || !element.name) {continue;}// ignore anyhting that is not considered a success fieldif (!k_r_success_contrls.test(element.nodeName) ||k_r_submitter.test(element.type)) {continue;}var key = element.name;var val = element.value;// we can't just use element.value for checkboxes cause some browsers lie to us// they say "on" for value when the box isn't checkedif ((element.type === 'checkbox' || element.type === 'radio') && !element.checked) {val = undefined;}// If we want empty elementsif (options.empty) {// for checkboxif (element.type === 'checkbox' && !element.checked) {val = '';}// for radioif (element.type === 'radio') {if (!radio_store[element.name] && !element.checked) {radio_store[element.name] = false;}else if (element.checked) {radio_store[element.name] = true;}}// if options empty is true, continue only if its radioif (val == undefined && element.type == 'radio') {continue;}}else {// value-less fields are ignored unless options.empty is trueif (!val) {continue;}}// multi select boxesif (element.type === 'select-multiple') {val = [];var selectOptions = element.options;var isSelectedOptions = false;for (var j=0 ; j<selectOptions.length ; ++j) {var option = selectOptions[j];var allowedEmpty = options.empty && !option.value;var hasValue = (option.value || allowedEmpty);if (option.selected && hasValue) {isSelectedOptions = true;// If using a hash serializer be sure to add the// correct notation for an array in the multi-select// context. Here the name attribute on the select element// might be missing the trailing bracket pair. Both names// "foo" and "foo[]" should be arrays.if (options.hash && key.slice(key.length - 2) !== '[]') {result = serializer(result, key + '[]', option.value);}else {result = serializer(result, key, option.value);}}}// Serialize if no selected options and options.empty is trueif (!isSelectedOptions && options.empty) {result = serializer(result, key, '');}continue;}result = serializer(result, key, val);}// Check for all empty radio buttons and serialize them with key=""if (options.empty) {for (var key in radio_store) {if (!radio_store[key]) {result = serializer(result, key, '');}}}return result;
}function parse_keys(string) {var keys = [];var prefix = /^([^\[\]]*)/;var children = new RegExp(brackets);var match = prefix.exec(string);if (match[1]) {keys.push(match[1]);}while ((match = children.exec(string)) !== null) {keys.push(match[1]);}return keys;
}function hash_assign(result, keys, value) {if (keys.length === 0) {result = value;return result;}var key = keys.shift();var between = key.match(/^\[(.+?)\]$/);if (key === '[]') {result = result || [];if (Array.isArray(result)) {result.push(hash_assign(null, keys, value));}else {// This might be the result of bad name attributes like "[][foo]",// in this case the original `result` object will already be// assigned to an object literal. Rather than coerce the object to// an array, or cause an exception the attribute "_values" is// assigned as an array.result._values = result._values || [];result._values.push(hash_assign(null, keys, value));}return result;}// Key is an attribute name and can be assigned directly.if (!between) {result[key] = hash_assign(result[key], keys, value);}else {var string = between[1];// +var converts the variable into a number// better than parseInt because it doesn't truncate away trailing// letters and actually fails if whole thing is not a numbervar index = +string;// If the characters between the brackets is not a number it is an// attribute name and can be assigned directly.if (isNaN(index)) {result = result || {};result[string] = hash_assign(result[string], keys, value);}else {result = result || [];result[index] = hash_assign(result[index], keys, value);}}return result;
}// Object/hash encoding serializer.
function hash_serializer(result, key, value) {var matches = key.match(brackets);// Has brackets? Use the recursive assignment function to walk the keys,// construct any missing objects in the result tree and make the assignment// at the end of the chain.if (matches) {var keys = parse_keys(key);hash_assign(result, keys, value);}else {// Non bracket notation can make assignments directly.var existing = result[key];// If the value has been assigned already (for instance when a radio and// a checkbox have the same name attribute) convert the previous value// into an array before pushing into it.//// NOTE: If this requirement were removed all hash creation and// assignment could go through `hash_assign`.if (existing) {if (!Array.isArray(existing)) {result[key] = [ existing ];}result[key].push(value);}else {result[key] = value;}}return result;
}// urlform encoding serializer
function str_serialize(result, key, value) {// encode newlines as \r\n cause the html spec says sovalue = value.replace(/(\r)?\n/g, '\r\n');value = encodeURIComponent(value);// spaces should be '+' rather than '%20'.value = value.replace(/%20/g, '+');return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
}

index.js
(我们要写的)

打开index.html,会有这样的效果:

在这里插入图片描述
而且点击”添加“按钮,会有弹框。

在这里插入图片描述


一、获取数据

1.首先,封装函数,功能:获取并渲染图书列表。
而且每打开/刷新一次网页,就获取并渲染列表一次,即调用函数。

// 封装-获取并渲染图书列表函数
function getBooksList() {// 函数体
}// 网页加载运行,获取并渲染列表一次
getBooksList()

2.获取数据(axios)

下图是接口文档截图。

在这里插入图片描述

在这里插入图片描述

// 封装-获取并渲染图书列表函数
function getBooksList() {// 1.1 获取数据axios({url:'https://hmajax.itheima.net/api/books',   // 接口文档有地址,最上面的框框params:{creator:'大鱼'    // 接口文档的“请求参数”,参数名 creator}}).then(result => {console.log(result)})
}// 网页加载运行,获取并渲染列表一次
getBooksList()

我们看一下控制台打印结果:
在这里插入图片描述

我们只想得到这个数组。

result.data.data
// 封装-获取并渲染图书列表函数
function getBooksList() {// 1.1 获取数据axios({url:'https://hmajax.itheima.net/api/books',   // 接口文档有地址,最上面的框框params:{creator:'大鱼'    // 接口文档的“请求参数”,参数名 creator}}).then(result => {console.log(result)const bookList = result.data.dataconsole.log(bookList)})
}// 网页加载运行,获取并渲染列表一次
getBooksList()

在这里插入图片描述

3.给自己起一个名字。
(一个图书管理系统嘛,经过每个用户编辑后的图书列表都不一样,但是不能影响别人的图书列表)

const creator = '大鱼'
// 封装-获取并渲染图书列表函数
function getBooksList() {// 1.1 获取数据axios({url:'https://hmajax.itheima.net/api/books',   // 接口文档有地址,最上面的框框params:{// creator: creator(参数名和参数值相同,简写)creator   // 接口文档的“请求参数”,参数名 creator}}).then(result => {console.log(result)const bookList = result.data.dataconsole.log(bookList)})
}// 网页加载运行,获取并渲染列表一次
getBooksList()

二、渲染数据

4.渲染数据

每一行图书对应的是 <tr></tr>
在这里插入图片描述

在这里插入图片描述

然后复制。

// 1.2 渲染数据const htmlStr = bookList.map(item => {return `<tr><td>1</td><td>JavaScript程序设计</td><td>马特·弗里斯比</td><td>人民邮电出版社</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr>`})console.log(htmlStr)
})

在这里插入图片描述

转换成字符串,并渲染到页面:

// 1.2 渲染数据const htmlStr = bookList.map(item => {return `<tr><td>1</td><td>JavaScript程序设计</td><td>马特·弗里斯比</td><td>人民邮电出版社</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr>`}).join('')console.log(htmlStr)document.querySelector('.list').innerHTML = htmlStr
})

在这里插入图片描述

修改内容:

在这里插入图片描述

        // 1.2 渲染数据
const htmlStr = bookList.map((item,index) => {return `<tr><td>${index + 1}</td><td>${item.bookList}</td><td>${item.author}</td><td>${item.publisher}</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr>`
}).join('')
console.log(htmlStr)
document.querySelector('.list').innerHTML = htmlStr
})

完整代码

const creator = '大鱼'
// 封装-获取并渲染图书列表函数
function getBooksList() {// 1.1 获取数据axios({url:'https://hmajax.itheima.net/api/books',   // 接口文档有地址,最上面的框框params:{// creator: creator(参数名和参数值相同,简写)creator   // 接口文档的“请求参数”,参数名 creator}}).then(result => {console.log(result)const bookList = result.data.dataconsole.log(bookList)// 1.2 渲染数据const htmlStr = bookList.map((item,index) => {return `<tr><td>${index + 1}</td><td>${item.bookList}</td><td>${item.author}</td><td>${item.publisher}</td><td><span class="del">删除</span><span class="edit">编辑</span></td></tr>`}).join('')console.log(htmlStr)document.querySelector('.list').innerHTML = htmlStr})
}// 网页加载运行,获取并渲染列表一次
getBooksList()

在这里插入图片描述


文章转载自:

http://ejUcYLRD.hxycm.cn
http://VO76mTBx.hxycm.cn
http://Bzj42JeI.hxycm.cn
http://6V78haEK.hxycm.cn
http://9TrrH7IM.hxycm.cn
http://P7Jqljrl.hxycm.cn
http://qQE5J2C8.hxycm.cn
http://8STHCTHZ.hxycm.cn
http://wJPD4n9X.hxycm.cn
http://jxXYn5uW.hxycm.cn
http://Pb5T3wpU.hxycm.cn
http://7WIxZGK0.hxycm.cn
http://xCl3Dzrx.hxycm.cn
http://krGiMjBJ.hxycm.cn
http://dnFxoKiH.hxycm.cn
http://XComy4WN.hxycm.cn
http://BqOExsNZ.hxycm.cn
http://6YmywYji.hxycm.cn
http://Z8WUOEso.hxycm.cn
http://UwChEH5m.hxycm.cn
http://x6b5Ryl1.hxycm.cn
http://iX2wgo2S.hxycm.cn
http://8LgvlWeF.hxycm.cn
http://cYDFn0CE.hxycm.cn
http://GXYDhjbm.hxycm.cn
http://ICRM8YOf.hxycm.cn
http://izLT4ll6.hxycm.cn
http://d87gA5OT.hxycm.cn
http://UF1WRWbF.hxycm.cn
http://EQoSWiB0.hxycm.cn
http://www.dtcms.com/a/383232.html

相关文章:

  • 在Excel和WPS表格中快速复制上一行内容
  • 11-复习java程序设计中学习的面向对象编程
  • 《云计算如何驱动企业数字化转型:关键技术与实践案例》
  • LSTM 深度解析:从门控机制到实际应用
  • FPGA学习篇——Verilog学习Led灯的实现
  • 【ARDUINO】Arduino Uno 获取 OV7576 数据并通过 ESP8266 发送到 TCP 客户端(待测试)
  • xtuoj 原根
  • JVM 核心知识全解析:从类加载到垃圾回收的深度认知
  • Cesium4--地形(OSGB到3DTiles)
  • NLP:Transformer之self-attention(特别分享3)
  • 07 常用损失函数
  • UDP Socket 进阶:从 Echo 到字典服务器,学会 “解耦” 网络与业务
  • 多语言编码Agent解决方案(4)-Eclipse插件实现
  • 深入理解线程模型
  • LMCache:KV缓存管理
  • 关于物联网的基础知识(三)——物联网技术架构:连接万物的智慧之道!连接未来的万物之网!
  • 《嵌入式硬件(十一):基于IMX6ULL的中断操作》
  • 【Pywinauto库】12.4 pywinauto.uia_element_info后端内部实施模块
  • 工程机械健康管理物联网系统:移动互联与多工况诊断的技术实现
  • python递归解压压缩文件方法
  • 深入 Spring MVC 返回值处理器
  • 黑马JavaWeb+AI笔记 Day05 Web后端基础(JDBC)
  • Open3D 射线投射(Ray Casting,Python)
  • RL【10-1】:Actor - Critic
  • 计算机视觉(opencv)实战二十一——基于 SIFT 和 FLANN 的指纹图像匹配与认证
  • 纯`css`固定标题并在滚动时为其添加动画
  • 金融科技:银行中的风险管理
  • 【办公类-113-01】20250914小2班生日手机备忘录提示、手机同屏到电脑UIBOT(双休日前移、节假日前移)
  • K8s学习笔记(二) Pod入门与实战
  • 如何下载Jemeter测试工具;如何汉化Jmeter2025最新最全教程!