Bootstrap <第一篇>

本文介绍了Bootstrap的基本使用方法,包括引入文件、响应式布局设置等,并详细解释了网格系统的使用技巧。

一、使用Bootstrap要引用的文件

  要使用Bootstrap,基本架构要引用如下文件:

    <link href="bootstrap.min.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" scr="jquery-1.10.2.min.js"></script>
    <script type="text/javascript" scr="bootstrap.min.js"></script>

  最简单的页面示例代码如下:

复制代码
<!doctype html>
<head>
    <meta charset="utf-8">
    <title>js</title>
    <link href="ace.min.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" scr="jquery-1.10.2.min.js"></script>
    <script type="text/javascript" scr="bootstrap.min.js"></script>
</head>
<body>
<div>
    <h1 class="btn btn-success btn-large"><i class="icon-user icon-white"></i>Hello,World</h1>
</div>
</body>
</html>
复制代码

  显示效果如下:

  

二、使用前要点

  1、DOCTYPE

  Bootstrap使用了HTML5元素,所以HTML头部要加上

<!DOCTYPE html>
<html>
....
</html>

  2、viewport

<meta name="viewport" content="width=device-width, initial-scale=1.0">
  • Width=device-width => 表示页面宽度是设备屏幕的宽度;确保网页能被不同屏幕分辨率的设备正确呈现;
  • user-scalable=no => 是否可以调整缩放比例(yes/no);
  • initial-scale=1.0 => 表示初始的缩放比例 ,以 1:1 的比例呈现,不会有任何的缩放;minimum-scale=0.5:最小允许的缩放比例;
  • maximum-scale=2.0:最大允许的缩放比例;

  如果maximum-scale=1.0 与 user-scalable=no 一起使用。这样禁用缩放功能后,用户只能滚动屏幕,就能让您的网站看上去更像原生应用的感觉。

  这样设置后,图片或元素也设置style="width:100%",那么图片看起来也是全屏的了。

  3、img-responsive响应式图像

  为图片加上img-responsive属性,可以让图片对响应式布局更加好。其样式如下:

.img-responsive {
  display: inline-block;
  height: auto;
  max-width: 100%;
}

  添加了此属性的图片会按比例缩小,但不能方法。

  而上面的直接设置width:100%会放大,可能会出现失真的情况。

三、Bootstrap网格系统

  1、网格系统是什么东西

  Bootstrap把一个页面分为12列,通过指定数字就能够设置宽度。简单的示例:

    <div class="row">
        <div class="col-xs-3">3</div>
        <div class="col-xs-6">6</div>
        <div class="col-xs-3">3</div>
    </div>

  显示效果如下:

  

  当浏览器的宽度缩小时(为下面说明响应式做铺垫),显示效果如下:

  

  要点:

  1、row是容器,网格样式要放在row容器里面。

  2、1个网页是12列。

  3、一共有4个前缀的网格class前缀,分别应用于分辨率的设备。

  图表如下:

  

  2、响应式网格

  示例说明:

    <div class="row">
        <div class="col-xs-12 col-sm-6 col-md-3">3</div>
        <div class="col-xs-12 col-sm-6 col-md-3">3</div>
        <div class="col-xs-12 col-sm-6 col-md-3">3</div>
        <div class="col-xs-12 col-sm-6 col-md-3">3</div>
    </div>

  显示效果如下:

  

  当浏览器缩小时:

  

  当再进一步缩小时:

  

  这就是所谓的响应式,说白了"响应式"就是根据浏览器的宽度来决定使用哪一个class,以上效果展示了响应式布局的原理:

  • 当屏幕宽度u≥1200px时,bootstrap会自动选用col-lg-*这个class;
  • 当屏幕宽度u≥992px时,bootstrap会自动选用col-sm-*这个class;
  • 当屏幕宽度u≥768px时,bootstrap会自动选用col-md-*这个class;
  • 当屏幕宽度u<768px时,bootstrap会自动选用col-lg-*这个class;

  3、偏移列

  偏移列的意思是隔开多少个列。

  示例:

    <div class="col-xs-12 col-sm-6 col-md-3">3</div>  //向右偏移2列了
    <div class="col-md-offset-2 col-xs-12 col-sm-6 col-md-3">3</div>

  显示效果如下:

  

  .col-xs=* 类不支持偏移,它们可以简单地通过使用一个空的单元格来实现该效果。

  这个样式相当于设置了margin:宽度*列数。

  4、嵌套列

  在网格里嵌套网格

复制代码
    <div class="row">
        <div class="col-xs-8">
            <div class="col-xs-2">2</div>
            <div class="col-xs-2">2</div>
            <div class="col-xs-2">2</div>
            <div class="col-xs-2">2</div>
        </div>
    </div>
复制代码

  输出效果如下:

  

  5、列排序

  通过使用".col-md-push-*"和".col-md-pull-*"能够互换顺序。其中*的范围从1到11。

  示例如下:

复制代码
    <div style="margin-top:20px"></div>
    无排序:
    <div class="row">
        <div class="col-sm-4">First</div>
        <div class="col-sm-8">Second</div>
    </div>
    有排序:
    <div class="row">
        <div class="col-sm-4 col-sm-push-8">First</div>
        <div class="col-sm-8 col-sm-pull-4">Second</div>
    </div>
复制代码

  显示效果如下:

  

  以上class使用的理解为:本来First占据4列,Second占据8列,如果要互换位置,则First要向右推(push)8个列,而Second要向左拉4个列。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>评论列表</title> <link rel="stylesheet" href="js/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="css/reset.css"> <link rel="stylesheet" href="css/iconfont.css"> <link rel="stylesheet" href="css/main.css"> <script src="js/jquery-1.12.4.min.js"></script> <script src="axios.min.js"></script> </head> <body> <div class="container-fluid"> <div class="common_title"> 评论列表 </div> <div class="container-fluid common_con"> <table class="table table-striped table-bordered table-hover mp20"> <thead> <tr> <th>作者</th> <th>评论</th> <th>评论在</th> <th>提交于</th> <th>状态</th> <th class="text-center" width="100">操作</th> </tr> </thead> <tbody> <tr> <td>小周</td> <td>这是一条测试评论,欢迎光临</td> <td>《世界,你好》</td> <td>2017-07-04 12:00:00</td> <td>已批准</td> <td class="text-center"> <a href="javascript:editTr( 'rejected',1 );" class="btn btn-warning btn-xs">拒绝</a> <a href="javascript:editTr( 'trashed',1 );" class="btn btn-danger btn-xs">删除</a> </td> </tr> <tr> <td>小右</td> <td>I am fine thank you and you?</td> <td>《世界,你好》</td> <td>2017-07-11 22:22:00</td> <td>已批准</td> <td class="text-center"> <a href="javascript:editTr( 'rejected',6 );" class="btn btn-warning btn-xs">拒绝</a> <a href="javascript:editTr( 'trashed',6 );" class="btn btn-danger btn-xs">删除</a> </td> </tr> <tr> <td>唐军</td> <td>好联律物联使进很们有严这里月之。实养件矿商除政究定划必火起划六。内百那则变次引持只情车各地织持。</td> <td>《第四篇示例文章》</td> <td>1970-04-24 11:22:29</td> <td>已批准</td> <td class="text-center"> <a href="javascript:editTr( 'rejected',11 );" class="btn btn-warning btn-xs">拒绝</a> <a href="javascript:editTr( 'trashed',11 );" class="btn btn-danger btn-xs">删除</a> </td> </tr> </tbody> </table> <div class="row text-center"> <ul class="pagination pagination-sm"> <li class="page-item first disabled"><a href="#" class="page-link">首页</a></li> <li class="page-item prev disabled"><a href="#" class="page-link">上一页</a></li> <li class="page-item active"><a href="#" class="page-link">1</a></li> <li class="page-item"><a href="#" class="page-link">2</a></li> <li class="page-item"><a href="#" class="page-link">3</a></li> <li class="page-item"><a href="#" class="page-link">4</a></li> <li class="page-item"><a href="#" class="page-link">5</a></li> <li class="page-item"><a href="#" class="page-link">6</a></li> <li class="page-item"><a href="#" class="page-link">7</a></li> <li class="page-item next"><a href="#" class="page-link">下一页</a></li> <li class="page-item last"><a href="#" class="page-link">尾页</a></li> </ul> </div> </div> </div> <script> // 设置左侧菜单 $('#release_btn').click(function () { window.parent.setMenu(0, 0); }) </script> <script> $(function () { const instance = axios.create({ baseURL: 'http://139.196.82.122:8080/api/v1', timeout: 5000, headers: { 'Content-Type': 'application/', "Authorization": localStorage.getItem("token"), } }); let totalPage = 0 async function getArticleList(page, perpage) { const { data } = await instance.get(`admin/comment/search?page=${page}&perpage=${perpage}`); if (data.code == 200) { $('tbody').empty(); totalPage = data.data.totalPage; data.data.data.forEach(element => { $('tbody').append(`<tr> <td>${element.author}</td> <td>${element.content}</td> <td>${element.title}</td> <td class="text-center">${element.date}</td> <td class="text-center">${element.state}</td> <td class="text-center"> <a href="javascript:editTr( 'rejected',11 );" data-id="${element.id}" class="btn btn-warning btn-xs">拒绝</a> <a href="javascript:deleteTr( ${element.id} );" data-id="${element.id}" class="btn btn-danger btn-xs">删除</a> </td> </tr>`); }); } else { alert("请求列表数据失败") } }; let page = 1; getArticleList(page, 10); $('.page-link').click(function (event) { if (event.target.text == "首页") { //首页 event.target.text 获取当前点击的文本 getArticleList(1, 10); return; } else if (event.target.text == "尾页") { getArticleList(totalPage, 10); return; } else if (event.target.text == "上一页") { if (page <= 1) { return; } getArticleList(page -= 1, 10); return; } else if (event.target.text == "下一页") { if (page == totalPage) { return; } getArticleList(page += 1, 10); return; } else { page = parseInt(event.target.text); getArticleList(page, 10); } }); $('tbody').on('click', '.btn-danger', async function (event) { event.preventDefault(); //阻止默认行为 const id = $(this).data("id"); //获取id let hr = confirm(id); if (hr) { if (!confirm("确定要删除这个评论吗?")) { return; } const { data } = await instance.delete(`/admin/comment/delete`, { id }); // 删除文章 if (data.code === 200) { alert("删除成功!"); // 重新获取当前页数据 getArticleList(page, 10); } else { alert("删除:" + data.msg); //提示错误信息 getArticleList(page, 10); //获取当前页数据 } } }); }); </script> </body> </html>为什么删除不了
最新发布
07-08
<think>根据提供的HTML和JavaScript代码,删除操作无法执行的原因可能有以下几点: 1. **删除请求的发送方式不正确**:在删除请求中,代码使用了`instance.delete`方法,但传递参数的方式不正确。Axios的delete方法通常将参数放在URL中(如`/admin/comment/delete?id=123`)或使用params对象。 2. **后端API可能需要特定的请求格式**:后端可能要求删除请求使用特定的参数传递方式(如URL参数或请求体)。 3. **确认对话框逻辑问题**:代码中使用了两次确认(`confirm`),但第一个`confirm`的用法不正确(`let hr = confirm(id);`),这可能会干扰用户操作。 4. **事件绑定问题**:删除按钮是动态生成的,使用事件委托绑定是正确的(`$('tbody').on('click', '.btn-danger', ...)`),但需要确保选择器正确。 ### 解决方案 #### 1. 修改删除请求 将删除请求改为使用URL参数传递id,或者使用params选项。 #### 2. 修正确认逻辑 将两次确认合并为一次,避免不必要的干扰。 #### 3. 确保正确获取id 使用`$(this).data('id')`获取id是正确的方式,但需要确保在生成按钮时正确设置了`data-id`属性。 ### 修改后的删除事件处理代码 ```javascript $('tbody').on('click', '.btn-danger', async function (event) { event.preventDefault(); const id = $(this).data('id'); if (confirm("确定要删除这个评论吗?")) { try { // 方式1:将id作为URL参数传递 const { data } = await instance.delete(`/admin/comment/delete?id=${id}`); // 方式2:使用params对象(根据axios文档,delete请求的第二个参数是配置对象,其中可以设置params) // const { data } = await instance.delete('/admin/comment/delete', { params: { id } }); if (data.code === 200) { alert("删除成功!"); getArticleList(page, 10); // 重新加载当前页 } else { alert("删除失败:" + data.msg); } } catch (error) { console.error("删除请求出错:", error); alert("删除请求出错,请查看控制台"); } } }); ``` ### 注意事项 1. **后端API的期望参数格式**:需要根据后端API文档确定是使用URL参数(如`?id=xxx`)还是请求体。对于DELETE请求,通常使用URL参数。 2. **错误处理**:添加try-catch块捕获可能的网络错误或请求异常。 3. **动态生成元素的事件绑定**:当前使用事件委托的方式绑定删除事件是合适的,因为按钮是动态生成的。 ### 完整代码调整 将原来的删除事件处理代码替换为上述修改后的代码。 ### 其他可能的问题 - **权限问题**:确保本地存储中的token有效,且具有删除评论的权限。 - **跨域问题**:如果后端没有正确配置CORS,删除请求可能被浏览器阻止。检查控制台是否有跨域错误。 §§相关问题§§: 1. 在Axios中,如何正确发送DELETE请求的参数? 2. 如何处理动态生成元素的事件绑定? 3. 如何优化前端确认对话框的用户体验? 4. 在删除操作后,如何局部刷新页面而不是重新加载整个表格?</think>根据提供的代码,删除功能无法工作的主要原因在于 `delete` 请求的实现方式不正确。以下是详细分析和解决方案: ### 问题分析 1. **Axios DELETE 请求格式错误**: ```javascript const { data } = await instance.delete(`/admin/comment/delete`, { id }); ``` Axios 的 `delete` 方法不能像这样传递参数对象。正确的方式是使用 `params` 或 URL 参数。 2. **双重确认逻辑问题**: ```javascript let hr = confirm(id); if (hr) { if (!confirm("确定要删除这个评论吗?")) { return; } // 删除操作... } ``` 这里使用了两个确认对话框,逻辑混乱且第一个 `confirm(id)` 显示的是 ID 值而不是提示信息。 3. **后端 API 可能要求特定格式**: 删除操作可能需要通过 URL 参数或请求体传递 ID,代码没有处理这些细节。 ### 完整解决方案 ```html <script> $(function () { const instance = axios.create({ baseURL: 'http://139.196.82.122:8080/api/v1', timeout: 5000, headers: { "Authorization": localStorage.getItem("token") || '', } }); let totalPage = 0; let currentPage = 1; const perPage = 10; // 获取评论列表 async function getCommentList(page = currentPage) { try { const { data } = await instance.get(`admin/comment/search?page=${page}&perpage=${perPage}`); if (data.code === 200) { $('tbody').empty(); totalPage = data.data.totalPage; currentPage = page; // 更新分页UI updatePaginationUI(); // 渲染评论列表 data.data.data.forEach(comment => { $('tbody').append(` <tr> <td>${comment.author}</td> <td>${comment.content}</td> <td>${comment.title}</td> <td>${comment.date}</td> <td>${comment.state}</td> <td class="text-center"> <button data-id="${comment.id}" class="btn btn-warning btn-xs reject-btn">拒绝</button> <button data-id="${comment.id}" class="btn btn-danger btn-xs delete-btn">删除</button> </td> </tr> `); }); } else { console.error("请求列表数据失败:", data.msg); alert("获取评论列表失败"); } } catch (error) { console.error("请求失败:", error); alert("网络请求失败"); } } // 更新分页UI状态 function updatePaginationUI() { $('.pagination li').removeClass('active disabled'); // 首页和上一页 $('.first, .prev').toggleClass('disabled', currentPage === 1); // 当前页激活 $(`.page-item:contains('${currentPage}')`).addClass('active'); // 下一页和尾页 $('.next, .last').toggleClass('disabled', currentPage === totalPage); } // 分页点击事件 $('.pagination').on('click', '.page-link', function(e) { e.preventDefault(); const text = $(this).text().trim(); if (text === "首页" && currentPage !== 1) { getCommentList(1); } else if (text === "尾页" && currentPage !== totalPage) { getCommentList(totalPage); } else if (text === "上一页" && currentPage > 1) { getCommentList(currentPage - 1); } else if (text === "下一页" && currentPage < totalPage) { getCommentList(currentPage + 1); } else if (!isNaN(text)) { const pageNum = parseInt(text); if (pageNum !== currentPage) { getCommentList(pageNum); } } }); // 删除评论 $('tbody').on('click', '.delete-btn', async function() { const id = $(this).data('id'); if (!confirm(`确定要删除ID为 ${id} 的评论吗?`)) return; try { // 方式1:URL参数传递 const { data } = await instance.delete(`admin/comment/delete?id=${id}`); // 方式2:请求体传递(如果后端需要) // const { data } = await instance.delete('admin/comment/delete', { data: { id } }); if (data.code === 200) { alert("删除成功!"); getCommentList(currentPage); // 刷新当前页 } else { alert(`删除失败: ${data.msg}`); } } catch (error) { console.error("删除请求失败:", error); alert("删除操作失败,请检查控制台"); } }); // 拒绝评论(类似删除逻辑) $('tbody').on('click', '.reject-btn', async function() { const id = $(this).data('id'); if (!confirm(`确定要拒绝ID为 ${id} 的评论吗?`)) return; try { // 假设拒绝接口为 PATCH /admin/comment/reject const { data } = await instance.patch(`admin/comment/reject`, { id }); if (data.code === 200) { alert("已拒绝评论!"); getCommentList(currentPage); } else { alert(`操作失败: ${data.msg}`); } } catch (error) { console.error("拒绝请求失败:", error); alert("操作失败"); } }); // 初始化页面 getCommentList(); }); </script> ``` ### 关键修复点: 1. **DELETE 请求正确实现**: ```javascript // URL参数方式 await instance.delete(`admin/comment/delete?id=${id}`); // 请求体方式 await instance.delete('admin/comment/delete', { data: { id } }); ``` 2. **简化确认逻辑**: ```javascript if (!confirm(`确定要删除ID为 ${id} 的评论吗?`)) return; ``` 3. **增强错误处理**: - 添加 try/catch 捕获所有异常 - 控制台输出详细错误 - 用户友好的提示信息 4. **分页状态管理**: - 添加 `currentPage` 状态变量 - 动态更新分页组件的激活状态 ```javascript function updatePaginationUI() { // 逻辑更新分页按钮状态 } ``` 5. **事件委托优化**: - 使用更精确的选择器 `.delete-btn` 替代 `.btn-danger` - 确保动态生成的按钮能正确绑定事件 ### 其他改进建议: 1. **添加加载状态**: ```javascript function showLoading() { $('tbody').html('<tr><td colspan="6" class="text-center">加载中...</td></tr>'); } async function getCommentList() { showLoading(); // 获取数据... } ``` 2. **API 响应处理**: ```javascript if (data.code !== 200) { throw new Error(data.msg || '未知错误'); } ``` 3. **Token 有效性检查**: ```javascript if (!localStorage.getItem("token")) { alert("请先登录"); window.location.href = "login.html"; return; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值