首先让我们回顾一下系列内容。

从零开始学Bootstrap(1)介绍了BootStrap最简单的模板,逐条解释了每行代码的含义。

从零开始学Bootstrap(2)强调了边学边做,通过实际的例子,讲解了如何一步一步的实现自己想要的效果。

写到这里,这篇从零开始学Bootstrap(3)我想写以下几个内容:

1. 基于我对Bootstrap的理解,做一个小小的总结。

2. 对从零开始学Bootstrap(2)例子进行UI美化和代码优化,主要是说说我是怎么做出自己想要的效果的。

3. 授人以鱼不如授人以渔,以自己的例子(因为自己也是新手,写出来的东西可能更适合初学者),讲讲代码编写过程中遇到的坑和需要注意的点。

废话不多说,下面开始:

一、   Bootstrap的小小总结

基于以Bootstrap的官方文档(http://v3.bootcss.com/)的说明,Bootstrap分为三个大块:CSS样式,组件,Javascript插件

首先要明确一点:Bootstrap是一个框架,意思就是别人造好了轮子,你可以直接拿来用,免去了自己去造轮子。所以咱们需要明确两点:这些轮子是什么样的轮子,怎么样去使用这些轮子

1. CSS样式:主要介绍了栅格系统和Bootstrap的全局样式。通过设定Class的值实现。

  1.1栅格系统:

  让我们可以很方便的实现HTML页面的布局(http://v3.bootcss.com/css/#grid)。

  我觉得栅格系统很重要。因为HTML页面的布局是很重要也很繁琐的一项任务(你看一下W3School里关于布局的介绍http://www.w3school.com.cn/html/html_layout.asp,看一下例子里的代码,就明白了),并且需要考虑到不同浏览器、不同设备的兼容性。

  栅格系统把这一切大大简化了。打开上面关于栅格系统的连接,你会发现只需要根据你想要实现的效果,给HTML元素Class属性赋相应的值,就可以实现,并且还能设置针对不同屏幕大小的设备展现不同的效果。

  1.2 Bootstrap全局样式:

  也就是Bootstrap对常用HTML元素(eg: DIV、Button、 P、 Table、 Img等等)是怎样美化的。通过给HTML元素的Class属性赋相应的值,就可以得到自己想要的效果。

  举一个最简单的例子:

如上图所示,Bootstrap可以让你仅仅改变Button元素的class的值就是改变按钮的大小,而不用很麻烦的去修改css文件,或者给元素内嵌style的值。

2. 组件:我认为组件就是Bootstrap把一些元素(HTML元素和Javascript代码)组合起来,就变成了组件,并且提供了很多很好看很实用的图标。这些组件基本都是HTML开发过程中常用的。通过设定Class的值实现。(http://v3.bootcss.com/components/)

举一个最简单的例子:

如上图所示,当我们需要实现导航功能的时候。找到Boostrap里相应的组件,依照其给的代码模板,根据自己的需求,赋相应的class和ul、li值就可以了

3. Javascript插件:我认为Bootstrap的Javascript插件就是封装了常用网页交互功能的”轮子”。只需要设定class属性和data属性就可以实现常用的网页交互功能,而不用自己写一大堆javascript代码。

首先说一个小插曲,新手可能误以为”javascript”和”java”有着很深的联系,甚至会认为javascript是java的变种。其实并不是这样,javascript是网景(Netscape)公司开发的应用于互联网的脚本语言,其实它最先的名字”是livescript”,后来网景公司与Sun公司(也就是发明Java的公司,后来被Oracle收购)达成合作,当时Java语言如日中天,名气很大,为了搭顺风车,就把livesript改名为javascript。以至于有人开玩笑:”Java”和”Javascrip”的区别就好比”雷锋”和”雷峰塔”的区别一样。

言归正传,我们知道,Javascript是为了赋予网页交互功能而存在的。所以,Bootsript上丰富的Javascript插件能够让你很方便的实现常用的网页交互功能,而不用把精力放在”造轮子”上。

如上图所示,利用Bootstrap的轮播插件(http://www.runoob.com/bootstrap/bootstrap-carousel-plugin.html, Bootstrap的官方文档这里没有翻译成中文,runoob上却有很详细的中文翻译,并且可以在线修改代码提交观察效果,强烈推荐),你可以很方便的实现现在很多网站都采用的图片轮播功能。这里只需要根据上述链接里面的教程,赋相应的class和图片src值就可以了,连data值都不用设。

二、   对从零开始学Bootstrap(2)例子进行UI美化和代码优化

下图是上期教程中实现的效果:

我们可以看到有以下几个缺点需要改正

  (1) 点击具体同学,显示其信息之后,没有处于被选中的状态。(你一开始点击,会处于被选中状态,但那只是button的点击效果,你点一下空白处,被选中的状态就消失了)

  (2) 色彩单调,不太美观。

  (3) 布局方面需要调整,信息框是呈现我们需要的信息的地方,应该尽可能大,最好其显示的时候能把不需要的框给隐藏起来。

  (4) 对于代码方面,对从零开始学Bootstrap(2)中的Javascript代码都写在HTML页面里了,并且有重复的代码段,应该把重复的代码段写成函数,这样可以减少代码体积,再一个修改代码的时候,我直接修改相应的函数就可以了,而不用一个地方一个地方的找。Javascript代码可以写到JS文件里,实现HTML页面和Javascript代码的分离。

技术选型(直白的说就是思考怎样利用Bootstrap框架里已有的东西,实现想要的效果):

1、首先调整布局,把信息框和同学框调整在一起,班级框显示在最上面。

显然,我们只需要把信息框所在的DIV和同学框的DIV放在同一个row的DIV里,并把修改跟栅格系统相关的class属性值”col-md”就可以实现。比如我们想让他们2:1的比例显示,那么信息框的class属性应该有col-md-8,而同学框的应该是col-md-4了。

值得注意的是,前端永远不可能是一步到位的开发,往往最开始的代码都不是我们想要的完美结果,需要细细调整。以下面为例,大家要学会自己搜,去尝试,去不断的调整(后面的调整,具体过程就不交代了):

我们修改完代码后,呈现的效果是下面这样的:

很明显的,上面每行只显示一个Class,有点浪费空间。下面的两个部分没有对齐。

把上面DIV组件的class属性里的”btn-group-vertical”删掉,把col-md-6添加到js代码里的tmp_button的class属性中。另外观察到这样设定了之后,第一行与第二行相比有奇怪的缩进:

毫无疑问,这种外观、布局类的变化跟CSS有关。这时候我们可以看一下元素具体的CSS。

以Chrome为例

在这个元素上点鼠标右键,选择Inspect,即审查,你会在右边的框里查到相应的代码。通过比对,我们发现是margin-left的问题,这个属性是bootstrap框架里默认的,从上层元素继承而来,有的为 -1px,有的为0px,我们只需要改成一样就可以了,比如都改成0px:

在js代码里的tmp_button,修改style属性,添加”margin-left:0px;”,有的人觉得字体居中不好看,可以添加text-align:left,设定按钮上的文字从左边起。

改正后的效果:

2、添加折叠按钮,让用户可以通过这个按钮隐藏/打开class框,点击classmate显示详细信息的时候,自动隐藏,以把大量的空间省给信息框来显示。

添加折叠按钮可以参考http://www.runoob.com/bootstrap/bootstrap-collapse-plugin.html 来实现。

另外,我们可以给折叠按钮加一个好看的图标,参考http://v3.bootcss.com/components/#glyphicons的教程就可以轻松实现。

实现点击classmate显示详细信息的时候,自动隐藏,需要修改classmate按钮的点击事件,即相应的js代码。

我们查看Bootstrap折叠插件的用法http://www.runoob.com/bootstrap/bootstrap-collapse-plugin.html(这个更好,官方的这部分还没翻译好),查到下面的内容:

原来Class属性里的cllapse和in值控制了隐藏和显示功能,那我们只需要在按钮的click事件js代码里修改相应的要进行”显示/隐藏”操作的HTML元素的class属性就可以了,于是在classmate按钮的click函数里添加以下语句就可以了:

$("#collapseOne").attr("class","panel-collapse collapse");

3、修正”点击具体同学,显示其信息之后,没有处于被选中的状态”的bug。

我们通过查阅文档,http://www.runoob.com/bootstrap/bootstrap-button-plugin.html, 给button的data-toggle属性设置为”button”,可以使其变成点击后自动呈现被选中的状态。

所以我们给classmate的button添加属性data-toggle=”button”。

此时又出现了另一个问题,我想接下去点击其他classmate的时候,原来点的还是处于激活状态,怎么办?

通过查阅http://www.runoob.com/bootstrap/bootstrap-buttons.html, button的class赋值有active时,才会呈现被选中的状态,也就是说,上面的设定,也就是bootstrap做了这么一件事情:当data-toggle=”button”的按钮被点击时,自动把active添加到class里,此时呈现被选中状态,当再次被点击时,自动把active从class里移除,就呈现未被选中的状态。

也就是说,我们只要自己去做这个操作,比如在点击classmate时,我可以把所有的classmate按钮的active都从class属性里移除,这样点击完成后,只有我最新点击的Button处于active状态。

因此,只需要在classmate按钮的click函数里加入这样的语句:

$(".btn-classmate").attr("class","btn btn-default btn-classmate btn-info");

效果如下图:

4、美化按钮外观

找到bootstrap里CSS关于按钮的部分:

http://www.runoob.com/bootstrap/bootstrap-buttons.html

按照教程修改,我这里只是简单的修改了一下按钮的颜色,大家可以按照需求自己改。效果如下图:

5、 HTML页面和Javascript代码的分离

其实分为两步:

第一步:把javascript代码放到js文件里,并在HTML文件里链接上。

第二步:把javascript里复用,或者有明确功能的代码块,写进一个函数里,直接调用函数。

由于这两步都比较简单,任何学过编程语言的应该都会。我就不展开写了。

值得注意的是,在链接JS文件时,要注意顺序。

比如Bootstrap的JS文件,里面的代码是基于Jquery写的,用了很多Jquery的函数,所以Jquery的JS文件要在Bootstrap的JS文件之前声明链接。

同理,咱们的JS文件时基于Bootstrap,所以要在Bootstrap之后,不然代码就不起作用了

最后国际惯例,贴一下相关的代码:

 getClassmate.html:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>getClassmate</title> <!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]--> <style type="text/css">
#btn-group-vertical-classes
{
overflow-y:auto;
overflow-x:auto;
height:100px;
}
#btn-group-vertical-classmates
{
overflow-y:auto;
overflow-x:auto;
height:500px;
}
button
{
text-overflow: ellipsis;
overflow: hidden;
border-radius: 0px;
}
#context_div
{
overflow-y:auto;
overflow-x:auto;
height:500px;
}
</style>
</head>
<body>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title" style="text-align:right;">
<a id="collapse_a" data-toggle="collapse" data-parent="#accordion"
href="#collapseOne">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> Click this to show/hide class
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
<div class="row" id="div1-classes-classmates">
<div class="btn-group-lg col-md-12" role="group" aria-label="..." id="btn-group-vertical-classes">
<!-- where classes show-->
</div>
</div>
</div>
</div>
</div> <br></br>
<div class="row">
<div class="btn-group-vertical btn-group-lg col-md-4 " id="btn-group-vertical-classmates" role="group" aria-label="...">
<!-- where classmates show-->
<button type="button" style="border-radius: 0px;" class="btn btn-default">Click class to show classmate.</button>
</div>
<div class="form-group">
<div class="col-md-8">
<div class="jumbotron" id="context_div">
<p>Click classmate to show details.</p>
</div>
</div>
</div>
</div>
</div> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="js/jquery-3.0.0.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
<script src="js/script_getClassmate.js"></script>
</body>
</html>

script_getClassmate.js:

$(document).ready(function(){
$.getJSON("resource/classmates.json",function(result){
$.each(result, function(i, field){
var tmp_button=$('<button type="button" style="border-radius: 0px; text-align:left; margin-left:0px" class="btn btn-default btn-class col-md-6 btn-success" data-toggle="button" chosen_state=0></button>').text(i);
tmp_button.attr("title",i);
$("#btn-group-vertical-classes").append(tmp_button);
});
$(".btn.btn-default.btn-class").click(function(){
var tmp_chosen=Number($(this).attr("chosen_state"))^1;
$(this).attr("chosen_state",String(tmp_chosen));
showClassmates(result);
$(".btn.btn-default.btn-classmate").click(function(){
$(".btn-classmate").attr("class","btn btn-default btn-classmate btn-info");
$("#collapseOne").attr("class","panel-collapse collapse");
var selected_classmate=$(this).text();
showClassmateDetail(result,selected_classmate);
});
});
});
}) function showClassmates(result){
$("#btn-group-vertical-classmates").empty();
var chosen_list=new Array(); $(".btn.btn-default.btn-class").filter(function(){
judgeflag=false;
if($(this).attr("chosen_state")=="1"){
judgeflag=true;
chosen_list.push($(this).text());
}
return judgeflag;
});
$.each(result,function(i,field){
var chosen_list_x;
for (chosen_list_x in chosen_list){
if(chosen_list[chosen_list_x]==i){
$.each(field,function(j,field2){
var tmp_button=$('<button type="button" style="border-radius: 0px;" class="btn btn-default btn-classmate btn-info" data-toggle="button" chosen_state=0></button>').text(j);
tmp_button.attr("title",j);
$("#btn-group-vertical-classmates").append(tmp_button);
});
}
}
});
} function showClassmateDetail(result,selected_classmate){
var classmate_context_item;
$("#context_div").empty();
$.each(result,function(i,field){
$.each(field,function(j,field2){
if(j==selected_classmate){
$.each(field2,function(k,field3){
//alert(k);
//alert(field3);
classmate_context_item=k + ": " + field3;
var tmp_p=$('<p></p>').text(classmate_context_item);
$("#context_div").append(tmp_p);
});
}
});
});
}

classmates.json:

{
"Class 001": {
"Xiao Wang": {
"Gender": "Male",
"Age": "18",
"Interest": "Football",
"Hometown": "Shanghai",
"Chinese": "78",
"Math": "90",
"English": "66",
"Physics": "81",
"Chemistry": "88",
"History": "69",
"Geography": "92"
},
"Xiao Li": {
"Gender": "Male",
"Age": "20",
"Interest": "Basketball",
"Hometown": "Beijing",
"Chinese": "98",
"Math": "77",
"English": "97",
"Physics": "72",
"Chemistry": "73",
"History": "88",
"Geography": "81"
}
},
"Class 002": {
"Xiao Cai": {
"Gender": "Female",
"Age": "19",
"Interest": "Dance",
"Hometown": "Gaoxiong",
"Chinese": "93",
"Math": "80",
"English": "92",
"Physics": "82",
"Chemistry": "77",
"History": "89",
"Geography": "83"
}
},
"Class 003": {
"Xiao Ma": {
"Gender": "Male",
"Age": "18",
"Interest": "Reading",
"Hometown": "Taibei",
"Chinese": "91",
"Math": "93",
"English": "96",
"Physics": "97",
"Chemistry": "100",
"History": "94",
"Geography": "92"
}
},
"Class 005": {
"Xiao Zhang": {
"Gender": "Male",
"Age": "20",
"Interest": "Running",
"Hometown": "Guangzhou",
"Chinese": "67",
"Math": "70",
"English": "66",
"Physics": "80",
"Chemistry": 68,
"History": "79",
"Geography": "93"
}
}
}

主要参考链接:

[1].Bootstrap中文官方文档

http://v3.bootcss.com/

[2].Runoob.com的Bootstrap教程

http://www.runoob.com/bootstrap/bootstrap-tutorial.html

从零开始学Bootstrap(3)的更多相关文章

  1. 从零开始学Bootstrap(2)

    继从零开始学Bootstrap(1)后,我们需要实际做一些页面,边学边做.因为前端是一项非常注意实践的技术,知识点太多.太琐碎了,所以我们只能边学边做.根据我们想要做的效果,去查相应的资料.不要想着把 ...

  2. 从零开始学Bootstrap(1)

    最近需要做一个简单的Web页面. 考虑到前端经验不足,为了快速产出,同时项目只是一个工具,对项目没有什么要求,所以我选择了Bootstrap这个框架作为Web框架. 写从零开始学Bootstrap的初 ...

  3. 从零开始学 Web 之 移动Web(七)Bootstrap

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  4. 从零开始学数据分析,什么程度可以找到工作?( 内附20G、5000分钟数据分析工具教程大合集 )

    从零开始学数据分析,什么程度可以找到工作?( 内附20G.5000分钟数据分析工具教程大合集 )   我现在在Coursera上面学data science 中的R programming,过去很少接 ...

  5. 从零开始学 Web 系列教程

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新…… github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http:/ ...

  6. 从零开始学 Web 之 移动Web(九)微金所案例

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  7. 从零开始学 ASP.NET Core 与 EntityFramework Core 目录

    从零开始学 ASP.NET Core 与 EntityFramework Core 介绍 我是一个目录,它旨在帮助开发者循序渐进的了解 ASP.NET Core 和 Entity Framework ...

  8. 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)

    Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...

  9. 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)

    你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...

随机推荐

  1. Hibernate 根据实体名称得到DB表名以及表对应的Sequence name

    DB: oracle 10g; entityName:com.signaldemand.flank.hibernate.model.实体名 1. 根据实体名获取DB表相对应的表名 Class<? ...

  2. 对CLR基本原理概念&垃圾回收机制的简单理解

    前言,之前有说过C语言的函数&变量的一些基本概念,说得可能不是很好,先也把C#的.里相关的也说下,已成一统. 而说函数变量,其实主要就是GC,而GC又是CLR的主要内容,故就有了此文. CLR ...

  3. 缺jstl.jar包导致的代码出现异常

    java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config 看报错中的红色部分,意思是缺类异常,再看后面蓝色粗体倾斜部分, ...

  4. 用T-sql 实现Oracle Connect by 的功能

    ; with subDepartment as ( select BesonDepartmentID, DepartmentName, ParentBesonDepartmentID, 1 as Hi ...

  5. Daily Scrum 12.1

    今日完成任务: 完成了对源代码结构的修改,删除冗余等:和其他小组讨论了关于整合的问题,向其他小组介绍自己小组使用的数据库等. 明日任务: 晏旭瑞 初步完成文档上传下载 孙思权 深入了解数据库中每个表, ...

  6. UIMenuController 实现长按显示自定义菜单功能

    这段时间在集成使用融云聊天功能的时候,想自定义消息cell的长按的菜单,在网上查了查,这是根据 UIMenuController 实现的.具体代码如下,我是使用一个btn实现的 首先创建一个btn,并 ...

  7. 解决Failed to load class "org.slf4j.impl.StaticLoggerBinder"

    Hibernate使用SLF4J API记录日志,所以在Hibernate的lib中,不再提供Log4J的包,而大部分框架依然使用Log4J记录日志,这样导致了兼容性问题. 解决办法,两步: 一.在编 ...

  8. HTML5的touch事件

    HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...

  9. Source Depot 使用总结

    MS使用的Source Depot方案,主要是控制软件版本,类似的软件有SVN等,Source Depot一般使用起来也比较方便,可以灵活的配置,只要有访问权限,就可以下到对应的源代码文件. SD使用 ...

  10. 【10_169】Majority Element

    今天遇到的题都挺难的,不容易有会做的. 下面是代码,等明天看看Discuss里面有没有简单的方法~ Majority Element My Submissions Question Total Acc ...