Bootstrap
“Bootstrap 包含了一个响应式的、移动设备优先的、不固定的网格系统,可以随着设备或视口大小的增加而适当地扩展到 12 列。它包含了用于简单的布局选项的预定义类,也包含了用于生成更多语义布局的功能强大的混合类。”
Bootstrap响应式开发
让我们来理解一下上面的语句。Bootstrap 3 是移动设备优先的,在这个意义上,Bootstrap 代码从小屏幕设备(比如移动设备、平板电脑)开始,然后扩展到大屏幕设备(比如笔记本电脑、台式电脑)上的组件和网格。
移动设备优先策略
内容
决定什么是最重要的。
布局
优先设计更小的宽度。
基础的 CSS 是移动设备优先,媒体查询是针对于平板电脑、台式电脑。
渐进增强
随着屏幕大小的增加而添加元素。
响应式网格系统随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列。

响应式工具
为了加快对移动设备友好的页面开发工作,利用媒体查询功能并使用这些工具类可以方便的针对不同设备展示或隐藏页面内容。另外还包含了针对打印机显示或隐藏内容的工具类。
有针对性的使用这类工具类,从而避免为同一个网站创建完全不同的版本。相反,通过使用这些工具类可以在不同设备上提供不同的展现形式。
可用的类
通过单独或联合使用以下列出的类,可以针对不同屏幕尺寸隐藏或显示页面内容。

通过了解以上的文档和理解响应式开发工具,我们便可以开始进行我们的开发实例,构建一个响应式的网页完成后如下:

我们可以看到这个页面有五个部分
1.顶部导航栏
2.左侧信息栏
3.中间网页主体
4.右侧信息栏
5.右边恻导航栏
通过分析网站布局,我们可以拟定这样一个HTML结构:
<!DOCTYPE html> <html> <body> <p class="navbar navbar-fixed-top navbar-default" role="navigation"> </p> <p class="container"> <p class="row"> <p class="col-md-3 col-sm-4"> </p> <p class="col-md-6 col-sm-8"> </p> <p class="col-md-3 hidden-sm hidden-xs"> </p> </p> </p> <p class="rightNav"> </p> </body> </html>
好了,上面的结构已经搭建好了。解释一下上面的几个p类:
首先是顶部导航栏,使用了.navbar初始化导航栏 .navbar-fixed-top将导航栏锁定到顶部 .navbar-default导航栏默认样式
其次,初始化一个响应式框架,.container在这个p里面添加一个.row的p,用来调整布局,这个.row的类里面放置三个网页主体模块左中右,这里在浏览器窗口都是大于md的时候中间占容器的一半,左右两个p分别占剩下的一半,当浏览器的窗口小于sm的时候隐藏右侧栏,并加宽中间的主窗口.
最后,添加一个右侧导航栏
这样,我们就能初步实现在不同尺寸的设备上产生不同的效果了.

让页面更加实用
右侧导航栏
我们设计的右侧导航栏的HTML代码如下:
<p id="bottomNav" class="bottom-tools" style="top: 600px; width: 67px;height:100%;visibility: hidden"> <p id="btn-nav" class="btn-group-vertical"> <p title="联系我们"><span class="icon-phone"></span></p> <a href="https://github.com/chation" target="_blank"> <p title="访问在GitHub上的主页"><span class="icon-github-alt"></span></p> </a> <p title="扫一扫"><span class="glyphicon glyphicon-qrcode"></span></p> <a style="visibility: hidden" id="sToTop"> <p title="返回顶部"><span class="icon-angle-up"></span></p> </a> </p> </p>
需求:
1.随窗口大小改变而改变位置,始终在屏幕可见的地方,并在右侧
2.当使用者向下滑动页面后才会显示返回顶部按钮,在顶部时不显示
随之,我们编写js代码:
/* 设置导航栏的偏移量 */ function navPosition() { var windowHeight = window.screen.availHeight; var windowWidth = document.body.clientWidth; var pMainWidth = document.getElementById("pMain").clientWidth; var navWidth = Math.ceil((windowWidth - pMainWidth) / 2 + pMainWidth) + "px"; var navHeight = windowHeight - Math.ceil(windowHeight / 2); var nav = document.getElementById("bottomNav"); if ((windowWidth - pMainWidth) < 67) { nav.style.left = (document.body.clientWidth - 66) + "px"; nav.style.top = navHeight + "px"; nav.style.display = "block"; nav.style.visibility = ""; } else { nav.style.left = navWidth; nav.style.top = navHeight + "px"; nav.style.display = "block"; nav.style.visibility = ""; } } /* 窗口resize之后重新调用navPosition设置偏移量 */ function navPositionResize() { window.addEventListener("resize", navPosition, false); } window.addEventListener("scroll", function () { //判断是否显示返回顶部按钮 var scrollTopElem = document.getElementById("sToTop"); if ((document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop) > 225) { scrollTopElem.style.visibility = ""; } else { scrollTopElem.style.visibility = "hidden"; } }, false);
这里,讲解一下我的思路:
让这个导航栏在主p(也就是放左中右三个p的容器)的大小被浏览器窗口大小减去后的值小于我们导航栏的宽度67px时,就让导航栏贴近屏幕右边侧,反之,则让导航栏的左边贴近主p的右侧,这样显得更为美观.
其次,我让这个导航栏始终显示在页面二分之一的位置
最后,监听是否显示返回顶部按钮,代码如下:
window.addEventListener("scroll", function () { //判断是否显示返回顶部按钮 var scrollTopElem = document.getElementById("sToTop"); if ((document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop) > 225) { scrollTopElem.style.visibility = ""; } else { scrollTopElem.style.visibility = "hidden"; } }, false);
1、各浏览器下 scrollTop的差异
IE6/7/8:
对于没有doctype声明的页面里可以使用 document.body.scrollTop 来获取 scrollTop高度 ;
对于有doctype声明的页面则可以使用 document.documentElement.scrollTop;
Safari:
safari 比较特别,有自己获取scrollTop的函数 : window.pageYOffset ;
Firefox:
火狐等等相对标准些的浏览器就省心多了,直接用 document.documentElement.scrollTop ;
2、获取scrollTop值
完美的获取scrollTop 赋值短语 :
var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
通过这句赋值就能在任何情况下获得scrollTop 值。
仔细观察这句赋值,你发现啥了没??
没错, 就是 window.pageYOffset (Safari) 被放置在 || 的中间位置。
因为当 数字0 与 undefine 进行 或运算时,系统默认返回最后一个值。即或运算中 0 == undefine ;
当页面滚动条刚好在最顶端,即scrollTop值为 0 时。 IE 下 window.pageYOffset (Safari) 返回为 undefine ,此时将window.pageYOffset (Safari) 放在或运算最后面时, scrollTop 返回 undefine , undefine 用在接下去的运算就会报错咯。
而其他浏览器 无论 scrollTop 赋值或运算顺序如何都不会返回 undefine. 可以安全使用..
所以说到头还是IE的问题咯. 杯具…
精神有点恍惚,不知道有没有表达清楚。
不过最后总结出来这句实验过OK,大家放心使用;
var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
底部添加注册按钮
在前面介绍到,通过响应式开发工具,我们隐藏了部分”不重要的内容”,为了使页面保持功能的完善,我们需要让注册的界面以另一种方式显示出来!
我们先添加一段HTML代码:
<nav id="smallScreen-nav" class="navbar navbar-default navbar-fixed-bottom" role="navigation" style="visibility: hidden"> <p class="row"> <p style="padding-top: 8px" class="col-xs-6"> <a href="#" class="btn btn-danger btn-block" role="button">注 册</a></p> <p style="padding-top: 8px" class="col-xs-6"> <a href="#" class="btn btn-success btn-block" role="button">登 录</a></p> </p> </nav>
这里,我们初始化一个底部导航栏,这个导航栏只有两个按钮,一个登陆,一个注册
我们继续添加js代码让他能在浏览器窗口小于指定大小的时候自动显示在底部~
var bNav = document.getElementById("smallScreen-nav"); if (windowWidth < 973) { bNav.style.visibility = ""; } else { bNav.style.visibility = "hidden"; } }
然后我们把它同上一个部分的js封装到一起,并作为window.addEventListener的参数函数传入进去



以上是添加了一系列效果之后的样式.
滑动到顶部的动画效果
普通的滑动到顶部只是迅速跳转到网页顶部,而没有实现滑动的动画效果,
包括jquery的方法
$('#elem').click(function(){ $('html,body').animate({ scrollTop: '0px' }, 500); });
这里虽然实现了动画效果,但是如果网页非常非常的长,那该怎么办,所以这里我决定让滑动效果看起来更加的平滑,让网页距顶部越远的时候一次滑动的越多,越近的时候越小.
首先,我们需要算出当前网页到顶部的距离,然后每次移动取它的百分之十,代码如下:
function moveToTOP() { var dist = Math.ceil((document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop) / 10); //这里采用Math.ceil()表示向上取整,因为像素距px是没有小数的 window.scrollBy(0, -dist); var scrollDelay = setTimeout('moveToTOP()', 10); //每0.01s,调用自身 var sTop = document.documentElement.scrollTop + document.body.scrollTop; if (sTop === 0) { clearTimeout(scrollDelay); } }
这样我们的网页返回顶部的效果就更加平滑了
总结
通过与上一篇博文结合下来,我们就写出了一个初具模型的社区页面了,这里贴一下我的全部代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Bootstrap学习笔记</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="../css/bootstrap.min.css"/> <link rel="stylesheet" href="../css/font-awesome.min.css"/> <link rel="stylesheet" href="../css/learnBootstrap.css"/> <link rel="stylesheet" href="../css/layout.css"/> <link rel="icon" href="../image/boot.ico"/> <script src="../js/jquery-3.0.0.min.js"></script> <script src="../js/bootstrap.min.js"></script> <script src="../js/layout_for_page.js"></script> </head> <body style="padding-top: 50px"> <p class="navbar navbar-fixed-top navbar-default" role="navigation"> <p class="container"> <p class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#"><span class=" icon-cloud"></span> 互动社区</a> </p> <p class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="#"><span class="icon-comments"> 主页</span></a></li> <li><a href="#"><span class="icon-envelope-alt"> 消息<span class="badge pull-right">3</span></span></a></li> <li><a href="#"><span class="icon-suitcase"> 话题</span></a></li> <li><a href="#"><span class="icon-camera"> 发现</span></a></li> </ul> <form class="pull-right navbar-form navbar-left" role="search"> <p class="form-group"> <input id="top-nav-search" type="text" class="form-control" placeholder="找人..."> </p> <button type="submit" class="btn btn-primary">搜 索</button> </form> </p><!-- /.nav-collapse --> </p><!-- /.container --> </p> <!--主页面开始--> <p id="pMain" class="container"> <p class="row"> <p class="col-md-3 col-sm-4"> <p id="left-window"> <p id="user_info"> <p id="user_head_top_img" style="background-image: url(../image/user_head_img.png)"></p> <p style="text-align: center"> <img class="user_head img-circle" src="upload/20161223122910-192.168.1.109.jpg" alt="user head img"> </p> <p style="padding-left: 15px;padding-right: 15px;text-align: center" class="caption"> <h3 id="user-name">恰西</h3> <p>人生可以热烈如一场拳击,也可以轻盈如一场游戏</p> <p> <a href="#" class="btn btn-warning" role="button">关 注</a> <a href="#" class="btn btn-success" role="button">私 信</a> </p> </p> </p> </p> </p><!-- 左窗口--> <p class="col-md-6 col-sm-8"> <p id="center-window"> <p id="textBox_new"> <textarea id="textBox-input" prefix type="text" class="form-control" placeholder="有什么开心的事,快告诉你的朋友们吧~"></textarea> <p id="button-textBox"> <p class="btn-group btn-group-sm"> <button type="button" class="btn btn-default"><span class="icon-star"></span> 表情</button> <button type="button" class="btn btn-default"><span class="icon-camera"></span> 图片</button> <button type="button" class="btn btn-default"><span class="icon-comment"></span> 话题</button> </p> <a href="#" class="btn btn-success pull-right" role="button">发 表</a> </p> </p> </p> <p class="active-main"> <p class="row"> <p class="col-xs-2"> <a href="javascript:void(0)"><img class="img-responsive img-circle" src="upload/20161223122910-192.168.1.109.jpg" alt="user head img"></a> </p> <p class="col-xs-10"> <p class=""> <p class=""> <small class="pull-right">4 分钟</small> <h4><a href="javascript:void(0)">恰西</a></h4> </p> <p class="user-text"> JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为javascript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。 </p> </p> </p> </p> </p> <p class="active-main"> <p class="row"> <p class="col-xs-2"> <a href="javascript:void(0)"><img class="img-responsive img-circle" src="upload/gouzei.jpg" alt="user head img"></a> </p> <p class="col-xs-10"> <p class=""> <p class=""> <small class="pull-right">12 分钟</small> <h4><a href="javascript:void(0)">炉石萌萌哒的狗贼丶</a></h4> </p> <p class="user-text"> 我打炉石真菜!远远没有恰西同学一半厉害,唉,好气啊! </p> </p> </p> </p> </p> <p class="active-main"> <p class="row"> <p class="col-xs-2"> <a href="javascript:void(0)"><img class="img-responsive img-circle" src="upload/qdwxj.jpg" alt="user head img"></a> </p> <p class="col-xs-10"> <p class=""> <p class=""> <small class="pull-right">33 分钟</small> <h4><a href="javascript:void(0)">晴天</a></h4> </p> <p class="user-text"> 哇!连续两天开传说!人品爆表!!! </p> <p class="user_text_img"> <img class="img-responsive" src="../image/img1.png"/> <img class="img-responsive" src="../image/img2.png"/> </p> </p> </p> </p> </p> </p><!-- 主窗口--> <p class="col-md-3 hidden-sm hidden-xs"> <p class="alert alert-warning alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <strong>提示:</strong> 注册成为我们的一员,你将拥有更大的朋友圈,更宽广的视角... </p> <p id="inputBox"> <h3>还没有帐号?</h3> <p>填写以下信息加入我们吧~!</p> <form id="form1"> <p> <p id="p-user_name" class="input-group"> <span class="input-group-addon" id="sizing-addon2"><i class="glyphicon glyphicon-user"></i></span> <input required id="user_name" type="text" class="form-control" placeholder="你的昵称"> </p> </p> <p> <p id="p-email_address" class="input-group"> <span class="input-group-addon"><i class="icon-envelope"></i></span> <input id="email_address" class="form-control" type="text" placeholder="邮箱地址"> </p> </p> <p> <p id="p-password" class="input-group"> <span class="input-group-addon"><i class="icon-key"></i></span> <input id="password" class="form-control" type="password" placeholder="设置密码"> </p> </p> <a id="login_to" class="btn btn-block btn-success"> <i class="glyphicon glyphicon-log-in"></i> 注 册</a> </form> <p> </p> </p> </p><!-- 右窗口--> </p> <p style="height: 3000px"></p> </p><!-- 主窗口结束 --> <p id="bottomNav" class="bottom-tools" style="top: 600px; width: 67px;height:100%;visibility: hidden"> <p id="btn-nav" class="btn-group-vertical"> <p title="联系我们"><span class="icon-phone"></span></p> <a href="https://github.com/chation" target="_blank"> <p title="访问在GitHub上的主页"><span class="icon-github-alt"></span></p> </a> <p title="扫一扫"><span class="glyphicon glyphicon-qrcode"></span></p> <a style="visibility: hidden" id="sToTop"> <p title="返回顶部"><span class="icon-angle-up"></span></p> </a> </p> </p><!-- 侧面nav栏 --> <nav id="smallScreen-nav" class="navbar navbar-default navbar-fixed-bottom" role="navigation" style="visibility: hidden"> <p class="row"> <p style="padding-top: 8px" class="col-xs-6"> <a href="#" class="btn btn-danger btn-block" role="button">注 册</a></p> <p style="padding-top: 8px" class="col-xs-6"> <a href="#" class="btn btn-success btn-block" role="button">登 录</a></p> </p> </nav><!-- 底部登陆栏--> </body> </html>
CSS代码如下:
#targets_ > p > a { margin-top:1%; margin-right:1%; } body{ background-color: #F6F9FA; } .navbar { /*opacity: 0.9;*/ } .bottom-tools { position: fixed; text-align: center; } .btn-clicked { background-color: #00A1D6; color: #FFFFFF; } .btn-group-vertical>a:focus{ outline: none; } .btn-group-vertical>p:hover, .btn-group-vertical>a>p:hover{ background-color: #00A1D6; color: #FFFFFF; } .btn-group-vertical>p ,.btn-group-vertical>a>p{ width: 50px; height: 50px; color: #00A1D6; background-color: #F6F9FA; border: 1px solid #e5e9ef; cursor: pointer; margin-bottom: 10px; font-size: xx-large; border-radius: 12%; } .btn-group-vertical>p>span { line-height: 47px; } /*#top-nav-search:focus{*/ /*width:400px;*/ /*}*/ #pMain { margin-top: 14px; } .user_head{ width:35%; height: 35%; border: 3px solid #fff; margin-top: -47px; } #user_head_top_img{ width: 100%; height: 150px; background-color: #F7F7F9; background-size: cover; } #left-window{ background-color: #FFFFFF; border: 1px solid #e5e9ef; /*padding-left: 15px;*/ /*padding-right: 15px;*/ border-radius: 2%; } #center-window{ padding-top: 20px; background-color: #FFFFFF; border: 1px solid #e5e9ef; padding-right: 15px; padding-left: 15px; border-radius: 2%; } #inputBox { background-color: #FFFFFF; border: 1px solid #e5e9ef; padding-left: 15px; padding-right: 15px; border-radius: 2%; } #textBox_new{ padding-bottom: 13px; } #textBox-input{ width:100%; height: 80px; resize: none; } #button-textBox{ padding-top: 10px; } .active-main{ margin-top: 10px; padding-top: 20px; background-color: #FFFFFF; border: 1px solid #e5e9ef; padding-right: 15px; padding-left: 15px; border-radius: 2%; } .active-main>p>p>a>img { border: 1px solid #e5e9ef; } .user-text{ padding-bottom: 1em; padding-right: 1em; } .user_text_img{ padding-bottom: 1em; padding-right: 1em; } .user_text_img>img { display: inline; width:45%; }
JS代码:
/** * Created by Chation on 2016/12/23. */ addLoadEvent(formClick); addLoadEvent(navPosition); addLoadEvent(navPositionResize); addLoadEvent(unCloth); /* 判断是否为空,更改相应样式 */ function formClick() { var submit = document.getElementById("login_to"); var psw = document.getElementById("password"); var username = document.getElementById("user_name"); var email = document.getElementById("email_address"); var classes = ""; submit.addEventListener("click", function () { if (psw.value != "" && email.value != "" && username.value != "") { classes = this.getAttribute("class") + " disabled"; this.setAttribute("class", classes); this.innerHTML = "<i class='icon-refresh icon-spin'></i> 正在注册..."; } else { if (psw.value == "") { classes = psw.parentNode.getAttribute("class"); psw.parentNode.setAttribute("class", classes + " has-error"); } if (email.value == "") { classes = email.parentNode.getAttribute("class"); email.parentNode.setAttribute("class", classes + " has-error"); } if (username.value == "") { classes = username.parentNode.getAttribute("class"); username.parentNode.setAttribute("class", classes + " has-error"); } } }, false); var focus = function () { this.parentNode.setAttribute("class", "input-group"); }; username.addEventListener("focus", focus, false); email.addEventListener("focus", focus, false); psw.addEventListener("focus", focus, false); } /* 设置导航栏的偏移量 */ function navPosition() { var windowHeight = window.screen.availHeight; var windowWidth = document.body.clientWidth; var pMainWidth = document.getElementById("pMain").clientWidth; var navWidth = Math.ceil((windowWidth - pMainWidth) / 2 + pMainWidth) + "px"; var navHeight = windowHeight - Math.ceil(windowHeight / 2); var nav = document.getElementById("bottomNav"); var bNav = document.getElementById("smallScreen-nav"); if ((windowWidth - pMainWidth) < 67) { nav.style.left = (document.body.clientWidth - 66) + "px"; nav.style.top = navHeight + "px"; nav.style.display = "block"; nav.style.visibility = ""; } else { nav.style.left = navWidth; nav.style.top = navHeight + "px"; nav.style.display = "block"; nav.style.visibility = ""; } if (windowWidth < 973) { bNav.style.visibility = ""; } else { bNav.style.visibility = "hidden"; } } /* 窗口resize之后重新调用navPosition设置偏移量 */ function navPositionResize() { window.addEventListener("resize", navPosition, false); } /* 构建window.onLoad能运行多个函数的函数 */ function addLoadEvent(func) { var oldOnLoad = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function () { oldOnLoad(); func(); } } } /*动画效果返回顶部*/ function moveToTOP() { var dist = Math.ceil((document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop) / 10); window.scrollBy(0, -dist); var scrollDelay = setTimeout('moveToTOP()', 10); var sTop = document.documentElement.scrollTop + document.body.scrollTop; if (sTop === 0) { clearTimeout(scrollDelay); } } /* 加宽搜索框 */ function addWidthForSearch() { var windowWidth = document.body.clientWidth; var dist = Math.ceil(windowWidth / 12); var searchBox = document.getElementById("top-nav-search"); var searchBoxWidth = searchBox.clientWidth; var allWidth = dist + searchBoxWidth; searchBox.style.width = allWidth + "px"; } /* 未封装代码开始 */ function unCloth() { document.getElementById("sToTop").onclick = moveToTOP; //返回顶部 var searchBox=document.getElementById("top-nav-search"); var searchBoxWidth=searchBox.clientWidth; searchBox.addEventListener("focus", addWidthForSearch, false); searchBox.addEventListener("blur",function(){ searchBox.style.width=searchBoxWidth+"px"; },false); window.addEventListener("scroll", function () { //判断是否显示返回顶部按钮 var scrollTopElem = document.getElementById("sToTop"); if ((document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop) > 225) { scrollTopElem.style.visibility = ""; } else { scrollTopElem.style.visibility = "hidden"; } }, false); }
