讲分页的相关制作前,博主还是先填下自己在背景那挖的坑吧。
首先是适配。在移动互联网时代,基本上企业都希望自己的网页可以很好的在移动设备上跑,所以做适配 很重要。关于适配方案,博主采用的是根据设备宽度除以定值来得到一个比例,再利用这个比例来换算px成rem的方案,具体有不清楚的可以参考这篇文章:http://www.cnblogs.com/lyzg/p/4877277.html
还有一种适配方案是设置meta中的initial-scale的值来让网页自行换算px,大家可自行选择适配方案。
上效果图先(PC端移步上一节)。默认是只出现Navbar按钮,点击按钮后会出现列表。
代码方面,因为rem单位是根据文档根节点的font-size值来计算的(1rem=根节点的font-size的值),所以可先添加以下js代码来根据设备宽度设置根节点font-size(代码中的10可以根据需要自行更改)
<script type="text/javascript"> (function() { var html = document.getElementsByTagName("html")[0], oClientWidth = document.documentElement.clientWidth; html.style.fontSize = oClientWidth / 10 + "px"; })() </script> HTML代码与上一节基本一样,只是在#wrap中加多了个按钮做响应式操作。
<div id="wrap"> <button class="nav-list">Navbar</button> 因为样式中的单位基本换成了rem,所以代码也有所更改,重新贴上和背景相关的less代码吧。
/* --------------------- 根据不同设备提供不同大小的图片以优化资源 ------------------------- */ @media (max-width: 767px) { @bg-pic : "../images/bg_s.jpg"; body{ background: url(@bg-pic) center center no-repeat fixed; /*背景图片居中不重复并保持固定*/ } } @media screen and (min-width: 768px) { @bg-pic : "../images/bg.jpg"; body{ background: url(@bg-pic) center center no-repeat fixed; /*背景图片居中不重复并保持固定*/ } } /* ----------------------------------------------------------------------------------------- */ body{ background-size: cover; /*覆盖背景*/ } /*------------------------ 内容主体 -----------------------*/ #wrap{ margin: 0 .5rem; margin-top: .3rem; position: relative; /*导航 阴影和border相关的px值作了保留 */ .navbar li{ border: 1px solid lighten(@gray,20%); border-radius: 10px; cursor: pointer; text-align: center; font-size: 18px; -webkit-transition: 0.4s; transition: 0.4s; box-shadow: 3px 3px 5px darken(@gray,10%); &:nth-child(1){ background-color: lighten(@red,10%); } &:nth-child(2){ background-color: lighten(@orange,10%); } &:nth-child(3){ background-color: lighten(@yellow,10%); } &:nth-child(4){ background-color: lighten(@green,10%); } &:hover{ box-shadow: 7px 7px 8px darken(@gray,20%); a{ color: white; } } } } 看上面的代码是否一头雾水呢?靠这些代码怎么做出来的效果??额……其实还有下面这些。
大屏和PC端显示,采用了flex-box布局
/*----------------------------- 媒体查询 ---------------------------*/ @media screen and (min-width: 768px) { #wrap{ .navbar{ display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; -ms-flex-wrap: wrap; flex-wrap: wrap; li{ display: inline-block; min-width: .8rem; line-height: .4rem; margin-right: .3rem; } } } .nav-list{ /*隐藏小屏才出现的按钮*/ display: none; } 小屏时则将navbar隐藏,只显示一个替代按钮。通过点击按钮才弹出隐藏的navbar。
@media (max-width: 767px) { #wrap{ .navbar{ display: none; padding-top: .4rem; width: 100%; li{ display: inline-block; width: 100%; line-height: .3rem; margin-top: .05rem; } } } .nav-list{ width: 1rem; height: .4rem; position: absolute; top: 0;bottom: 0;left: 0;right: 0; margin: 0 auto; /*居中定位*/ font-size: 25px; border-radius: 10px; .btnColor(darken(aqua,10%),linear-gradient(white,black)); .btnColor(darken(aqua,10%),-webkit-linear-gradient(white,black)); cursor: pointer; z-index: 10; //防止被其他内容遮挡 box-shadow: 0 0 25px #111; &:hover{ color: lighten(aqua,10%); box-shadow: 0 0 25px white; } } nav-list的样式里用到了LESS语法里的mixin。很简单
/*--------------------- 按钮样式 ------------------------*/ .btnColor (@btnColor: black; @backgroundColor: white;){ color: @btnColor; background: @backgroundColor; }CSS方面总结下:
1.同一张图应该有多种大小的资源,以根据显示设备加载不同资源,防止造成浪费。
2.做响应式布局,同一元素的共用属性可不在媒体查询中编写。
3.利用display属性来灵活布局。
4.要熟练掌握不同元素(有无宽高等)的横竖居中方式。
5. 有些标签有默认font-size,如ul标签,需设置为0。
JS方面主要是处理小页面时的导航展示,简单的说就是先判断页面大小,再对小页面展示出来的按钮绑定个点击事件,改变Navbar的display值。
/*----------------------- 函数封装 ------------------------------*/ var myFn = { //判断节点是否存在相应的class hasClass : function(className,ele) { return new RegExp("(^|\\s)" + className + "(\\s|$)").test(ele.className); }, //通过节点的class来获取节点 getByClass : function(name,ele) { var ele = ele || document; if(ele.getElementsByClassName) { return ele.getElementsByClassName(name); } else { var allEle = ele.getElementsByTagName("*"), len = allEle.length, result = []; for (var i = 0; i < len; i++) { if(myFn.hasClass(name,allEle[i])) { //调用下面的hasClass函数 result.push(allEle[i]); } } return result; } }, // 事件兼容 addHandler : function(ele, type, handler) { if(ele.addEventListener) { ele.addEventListener(type, handler, false); } else if(ele.attachEvent) { ele.attachEvent('on' + type, handler); } else { ele['on' + type] = handler; } }, //获取样式 getStyle : function(obj,attr) { if(obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj,false)[attr]; } },
以上都是些常用函数的兼容性代码,把它们都封装在一个对象里来调用,防止命名冲突。
/*------------------------ 主程序 -----------------------------*/ var component = (function() { // 小屏时点击Navbar按钮展示组件 var showNavbar = function(size) { //size为传递过来的页面宽度 var oNavbar = myFn.getByClass("navbar")[0]; if(size < 768) { //判断是否为小页面的宽度 var oNavList = myFn.getByClass("nav-list")[0]; //获取小页面的按钮 oNavbar.style.cssText = "display: none"; //先让flex布局的导航隐藏 oNavList.onclick = function() { oNavbar.style.display = (myFn.getStyle(oNavbar,"display") === "none") ? "block" : "none";//通过按钮的点击事件显隐导航 } } else { oNavbar.style.cssText = "display: -webkit-box;display: -ms-flexbox;display: flex;"; //大页面则重新flex布局 } } return { //提供外部接口 showNavbar : showNavbar, pagination : pagination } window.onresize = function() { //页面改变时,获取当前宽度 var oEleWidth = document.documentElement.clientWidth; //获取屏幕宽度 component.showNavbar(oEleWidth); //传递宽度 }博主将页面要实现的功能和一些功能函数分成两个模块,用var fn = (function() {})()的模块模式编写代码,通过返回相应接口给外部提供功能引用,而不会造成过多的全局污染,也保护了私有变量。
JS总结:
1.时刻记得不要暴露过多的全局变量,全局变量越少越好
2.非必要的变量和函数私有化,防止被外部不小心更改了
3.代码兼容性
写oNavList这个按钮的点击事件时,博主遇到个坑——按钮点击后导航没展示出来,需要调整页面到特定尺寸才有反应!
经调试,导航没展示的情况也能触发点击事件里的完整代码,但就是不展现导航。。。当时那个一脸蒙蔽的= =||
考虑到兼容性,博主一开始写点击事件是这样的
myFn.addHandler(oNavlist,"click",function() {...})可曾想被这货坑了,至今被坑的不明觉厉。(貌似没啥毛病啊,而且偶尔可以起作用啊,不明白为什么有失常表现。有相同被坑经历的童鞋可以解释 下吗?)
后来直接改成.onclick后就解决了……
接下来讲分页啦,博主又踩了哪些坑呢?敬请期待……