接上文:前端篇1链接
写在前面,笔者并不是前端,以下均为笔者的理解与实现,如有不正确的说辞,还望指正。
目录
在线访问链接:链接
本文源码下载链接:链接
本文的脚本代码依赖于上篇的zq.js,在线预览。
上文我们讲到了几个简单的布局,下面就来画一个首页吧!
1、引入两大css框架
引入bootstrap跟font-awesome,这个font-awesome我们主要用到其中的图标跟字体,依赖于其自带的字体文件:
2、直接开撕(代码稍后给出):
以下几点比较关键:
1、响应式
在html的head标签内加入:
<meta name="viewport" content="width=device-width, initial-scale=1">
然后在css里就可以用媒体查询了。下面的意思就是当宽度小于1024像素时,加载其中的样式,加载的样式会覆盖之前的样式,通过这种手段,实现了不同分辨率下不同的样式。注意,这个宽度必须从大往小写(min-width反之)。只有这样,才能保证小分辨率的样式会始终覆盖大分辨率的样式
在做响应式开发的时候,宽度最小一般支持到360个像素左右即可。
2、布局
大家可以查看源代码,整体使用栅格布局,右上使用flex布局将三个内容居中对齐。
3、使用fixed定位固定导航栏
如图,导航栏随着滚动条滚动会始终保留在顶部,这点是很好实现的:
#top {
height: 80px;
background: var(--primary);
color: var(--white);
width: 100%;
position: fixed;
z-index: 999;
top: 0;
}
fixed定位跟absolute绝对定位非常相似,都拥有偏移量跟堆叠属性z-index。fixed绝对定位是基于浏览器窗口进行偏移,因此位置固定,不会随滚动条变化。absolute则是基于父标签的定位(父标签也是经过定位)或者html定位,位置相对于页面固定,但是会随滚动条变化。
因此为导航栏添加fixed绝对定位,设置偏移量在顶部,最后设置一个大一点的z-index,方便穿过其他dom元素。
注意:导航栏是可以这么做的,因为它的宽度是页面宽度的100%,对不同分辨率展现形式是一样的。但是fixed定位跟absolute定位在响应式开发中是最致命的两个定位,因为这两个定位已经摆脱了父元素的束缚,不同分辨率下展现效果完全不同。甚至能够在canvas之上,由于canvas放缩十分不灵活。这就要求我们要在每个分辨率下都要重新定位。
进阶:通过监听滚动条事件动态添加定位与回到顶部。
1、在滚动一定距离后导航栏滑下
要用到css如下,其中先用absolute定位导航栏,类标签scroll-top:position: fixed !important,其中!important的意思是强行使用该属性,因为我们后面可能会再次用到该类标签,由于后面的样式属性会覆盖前面相同的属性,为了防止被覆盖,就加了这个。slideInDown和slideInUp为我们滑下滑上的动画函数。
#top {
height: 80px;
background: var(--primary);
color: var(--white);
width: 100%;
position: absolute;
z-index: 900;
top: 0;
}
.scroll-top{
position: fixed !important;
}
.animated {
animation-duration: .6s;
animation-fill-mode: both;
}
.slideInDown{
animation-name: slideInDown
}
.slideInUp{
animation-name: slideInUp
}
@keyframes slideInDown {
from {
transform: translate3d(0, -100%, 0);
visibility: visible;
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes slideInUp {
from {
transform: translate3d(0, 0, 0);
visibility: visible;
}
to {
transform: translate3d(0, -100%, 0);
}
}
要用到的js如下,其中要给window元素添加监听滚动事件,当滚动距离超过400个像素时,动态添加class标签使其fixed定位到顶部,否则移除class标签。
zq.$(function () {
$(window).on("scroll", function() {
var scroll = $(window).scrollTop();//滚动的距离
zq.log(scroll);
if (scroll > 400) {
$("#top").addClass("scroll-top animated slideInDown").removeClass("slideInUp");
} else if (scroll < 400) {
zq.timeout(0).then(function() {
$("#top").addClass("slideInUp");
return zq.timeout(200);//promise实现顺序执行,0.2秒执行下面的方法,为了有一个比较平滑的感受
}).then(function() {
$("#top").removeClass("scroll-top animated slideInDown");
});
}
})
})
最后效果 是这样的:
2、回到顶部
依次添加html、样式及脚本代码即可:
<div class="returnTop">
<i class="fa fa-rocket" style="color: white;"></i>
<a href="#" onclick="javascript:void(0)">回到顶部</a>
</div>
.returnTop {
display: none;
background-color: var(--gray-dark);
padding-top: 2%;
position: fixed;
right: -100px;
top: 80%;
width: 6.25rem;
height: 6.25rem;
text-align: center;
z-index: 200;
}
.returnTop a:hover{
text-decoration: none;
color: var(--white);
}
在之前滚动一定距离后导航栏滑下的动图中可以看出,每次滚动条滚动都会触发多次滚动事件,我们在触发滚动事件每次都会动态做一些操作,这其实是很不好的。如下代码可以帮你有效优化这个问题:每次滚动事件触发时我们转换为判断两个变量是否相等(实际是判断是否穿过临界值),从而来决定是否去进行接下来的操作。这样一来,我们只会在临界值处执行我们不同的方法。
(听个音乐吧,网页链接,这个网页很简单,想学的点个赞呗)
返回顶部通过动画函数是很容易实现的,你也可以给a标签添加锚链接#(即href="#"),点击后直接返回页面顶端,只不过没有平滑的动画效果。其实我们在做页面很多情况下都会给a标签href="#"这个默认值,而且时常忘了删掉它,就会导致用户点上去很懵,反正我的体验是很不好。你可以用以下替换之,这就是为什么很多网站宁愿多写一段没用的οnclick="javascript:void(0)":
<a href="#" onclick="javascript:void(0)">hoppinzq</a>
<span>或者</span>
<a style="cursor:pointer" data-tip="鼠标移过来变小手">hoppinzq</a>
zq.$(function () {
var lastReturnTopStatus = false;
$(window).on("scroll", function() {
var scroll = $(window).scrollTop();
if (scroll > 400) {
$("#top").addClass("scroll-top animated slideInDown").removeClass("slideInUp");
} else if (scroll < 400) {
zq.timeout(0).then(function() {
$("#top").addClass("slideInUp");
return zq.timeout(200);
}).then(function() {
$("#top").removeClass("scroll-top animated slideInDown");
});
}
//增加一个自定义变量,记录是否该去显示“返回顶部”,这会防止频繁的操作dom
//这是因为滚动事件是一滚动就会触发很多次
if (scroll > 700) {
$(".returnTop").data("top", true);
} else {
$(".returnTop").data("top", false);
}
if ($(".returnTop").data("top") != lastReturnTopStatus) {
lastReturnTopStatus = $(".returnTop").data("top");
if (lastReturnTopStatus) {
//以下代码的意思是:当从最上面向下滚动700个像素时为类为returnTop的对象dom对象添加类标签scroll-top,
//然后使用show方法展示dom(就是将display置为block),在展示完成的回调函数里为dom对象添加向左缓慢移移动
//至right为0的位置。然后找到该dom下的a标签(就是那个“回到顶部”)添加点击事件,触发后将缓慢移动至html滚动条最上面
$(".returnTop").addClass("scroll-top").show(function() {
$(this).animate({
right: '0px'
}, "slow");
}).find("a").on("click", function() {
$("html, body").animate({
"scroll-top": 0
}, "slow");
});
} else {
//以下代码的意思是:当从上往下滚动少于700个像素时,先调用动画函数将dom元素向右移动100个像素,并且在0.5秒后隐藏
//dom元素,隐藏完成后将scroll-top移除,并且关闭a标签的点击事件
$(".returnTop").animate({
right: '-100px'
}, "slow").hide(500, function() {
$(this).removeClass("scroll-top");
}).find("a").off("click");
}
//这个顺序一定要注意,在显示前先添加类标签,为了防止标签内的样式会给用户一个视觉影响。然后显示在视窗外,最后通过动画把渲染后的dom移动至
//视窗内。。隐藏的时候必须先使用动画隐藏在视窗外,在用户的看不到的地方隐藏移除。
}
})
})
效果拔群:
4、给页面加上loading?
这个通过css加上即可,loading的样式大家上网上随便找一找gif或者svg的动图就行。也可以用css的动画去实现,这个难度比较大,但是能实现很多花样。我的loading就是随便找了一张gif动图,对应代码如下:
承载loading的html代码一定要加在body标签的后面,先让loading的dom加载在页面上
<div class="loading"></div>
样式没什么好说的,用一个背景图片居中,然后整个div铺平整个屏幕就行。还是用fixed定位,方便用户在滚动页面的时候都给遮住,在有透明度的时候,这个效果还是比较出色的。
.loading{
position:fixed;
left:0px;
top:0px;
width:100%;
height:100%;
z-index:999999;
background: var(--primary);
background-position:center center;
background-repeat:no-repeat;
background-image:url(../img/ploading.gif);
opacity: 0.99;
}
最后,在dom加载完毕时会触发DOMConteneLoaded事件(可看我上一篇博客前端篇1链接),我们监听该事件并绑定回调隐藏即可。你也可以在任意条件触发下隐藏,比如在某个接口初始化完成后隐藏,但是无论如何都要保证loading层可以隐藏掉。由于现在的dom加载都非常快,导致这个loading闪一下或者看不出效果,可以手动延迟一下隐藏,之后我会将其封装成一个组件。
$(".loading").delay(2000).fadeOut(500);//延迟2s隐藏,0.5s渐隐,也就是页面0.5s渐显
来吧展示:
最后,不同情形下的遮罩实现是完全不同的,我将在后面封装在我们自己的ajax组件里。这一版代码就不上了。
.preloader{
position:absolute;
left:0px;
top:0px;
width:100%;
height:100%;
z-index:999999;
background-color:#ffffff;
opacity: .75;
background-position:center center;
background-repeat:no-repeat;
background-image:url(img/preloader.svg);
}
function bindLoading($dom) {
if ($dom.find(".preloader").length > 0) {
$dom.find(".preloader").fadeIn();
return;
}
var {top,left} = $dom.get(0).getBoundingClientRect();
var {scrollTop,scrollLeft} = document.body;
var dom_width = $dom.width();
var dom_height = $dom.height();
var $preloader = $('<div></div>').addClass('preloader')
.height(dom_height).width(dom_width).offset({
top: top + scrollTop,
left: left + scrollLeft
})
$dom.prepend($preloader);
}
$(".panel").each(function(index,element){
bindLoading($(element).parent("div"));
})
5、导航栏导航?
网页设计到这里就有人问为什么不给导航栏加导航功能?或者tab页切换的功能?先安排上。
<div id="top" class="clearfix">
<div class="applogo">
<a href="#" class="logo">HOPPIN</a>
</div>
<a href="#" class="sidebar-open-button"><i class="fa fa-bars"></i></a>
<a href="#" class="sidebar-open-button-mobile"><i class="fa fa-bars"></i></a>
<h1 class="title">首页</h1>
<!--开始追加如下代码-->
<ul class="title-bar">
<li><a class="iframe_link iframe_active" href="http://hoppinzq.com">页面1</a></li>
<li><a class="iframe_link" href="http://hoppinzq.com:1234/test/index.html">页面2</a></li>
<li><a class="iframe_link" href="#">页面3</a></li>
<li><a class="iframe_link" href="#">页面4</a></li>
<li><a class="iframe_link" href="#">页面5</a></li>
</ul>
<!--追加完毕-->
<ul class="zq-user-bar">
<li class="zq-user-bar-img">
<img src="img/user-img.png" alt="">
</li>
<li class="zq-user-bar-msg">
<span>欢迎您,HOPPIN</span>
</li>
<li class="zq-user-bar-btn">
<a href="#" title="" class="btn-user" onclick="zomponent.msg(123,2000,{isPL:false});">注销</a>
</li>
</ul>
</div>
然后在页面任意位置加一个iframe:
<div class="content">
<div class="container-widget">
<div class="row">
<div class="col-md-12">
<div class="panel-widget banner-with-stats widget clearfix" style="height:450px;">
<div class="col-sm-12" style="height:450px;background: #fff">
<h4 class="title">这里是banner</h4>
<iframe class="iframe_mx" src="http://hoppinzq.com" scrolling="no">
</iframe>
</div>
<!--。。。。。。省略-->
对应样式如下:
.title-bar{
float: left;
display: flex;
height: 100%;
width: 60%;
}
.title-bar li{
width: 20%;
text-align: center;
line-height: 50px;
display: inline-block;
height: 3.125rem;
}
.title-bar a{
display: block;
margin-top: 15px;
color: #000;
height: 100%;
transition: 0.5s all;
border-right: 1px solid #fff;
}
.iframe_active{
background-color: #77ff9e;
}
.iframe_mx{
width: 100%;
height: 100%;
}
@media screen and (max-width: 760px){
.title-bar{
flex-direction: column;
}
}
首先,导航栏用html的排列标签ul跟li比较好,直接让li的float:left就可以实现向左排列。但是既然要做响应式的,最好给ul的布局为flex,然后让内部的li元素为水平轴方向排列(默认)也可以实现左排列。这样的话,在移动端的时候就可以动态改变li的排列方向为交叉轴(flex-direction: column)就能很好的自适应。
最后,对应js代码如下:
$(".iframe_link").click(function(){
$(this).addClass("iframe_active").parent("li").siblings().find("a").removeClass("iframe_active");
$(".iframe_mx").attr("src",$(this).attr("href"));
return false;//阻止冒泡,防止a标签跳转链接,也可以用event.stopPropagation();
})
来吧展示:
iframe对于我们的需求来说是最好实现的,我们仅仅把iframe内容填充html即可。但是要注意:iframe对于商用网站不友好,因为搜索引擎的检索程序无法解读iframe,不利于SEO(搜索引擎优化)。此外iframe内的网页会跟首页一样并行加载,首页的onload方法必须等待iframe加载完才能执行。iframe内的网页不能共用首页的静态资源,这样主页引用太多静态资源导致响应不是很好。
所以基于以上几点,目前商用网站几乎不用iframe填充html,你看到的导航栏其实是其他页面的内容而非主页,因为蜘蛛爬虫获取不到iframe的网页的关键字(或者你用其他方法把网页嵌入你的首页),也就是说你的博客或者视频无法被抓取到,导致别人搜索东西是不会展示你的相关页面。
但是iframe可以通过父子页面通讯来处理跨域问题,在一些上传、展示组件里也是用的非常多。
在线访问链接:链接
本文源码下载链接:链接
(未完待续。。。)