真的是好久都没有写博客了,这几个月一直很忙。这几天暑假在家,闲来无事,从前端到后台写了一个网站,算是新的个人博客吧。本文的demo和下载就挂在上面。
今天在这里分享一个十分常见的应用,轮播。我们经常在网站中看到slider,既实用又好看。这里主要用css和少量的jQuery(其实用原生js也很简单)来实现一个响应式的幻灯片slider。
这里主要给大家提供一种思路,还有实现中的一些细节处理,具体的功能,链接大家可以自己添加。废话不多说,我们先看一下预览效果,点击下面的链接:
responsive-slider
源码和资源文件在文末下载。
html主要框架
首先先简单地搭出以下框架:
index.html:
<!DOCTYPE html> <html> <head> <title>Slider</title> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <link rel="stylesheet" type="text/css" href="css/style.css" /> </head> <body> <p class="demo"> <p class="wrapper"> <ul class="img-slider"> <li><img src="images/img1.jpg" alt="First Image" /></li> <li><img src="images/img2.jpg" alt="Second Image" /></li> <li><img src="images/img3.jpg" alt="Third Image" /></li> <li><img src="images/img4.jpg" alt="Forth Image" /></li> <li><img src="images/img5.jpg" alt="Fifth Image" /></li> </ul> <ul class="img-thumbnails"> <li><img src="images/thumbnail/img1.jpg" alt="First Image" /></li> <li><img src="images/thumbnail/img2.jpg" alt="Second Image" /></li> <li><img src="images/thumbnail/img3.jpg" alt="Third Image" /></li> <li><img src="images/thumbnail/img4.jpg" alt="Forth Image" /></li> <li><img src="images/thumbnail/img5.jpg" alt="Fifth Image" /></li> </ul> </p> </p> </body> <script src="js/jquery-3.1.0.js" type="text/javascript"></script> <script src="js/index.js" type="text/javascript"></script> </html>
十分简单的代码,就不多说了,按照里面链接的路径放好资源文件,主要就是几个图片img1~img5,link中有一个style.css文件,body的最后引用jQuery库和index.js。
不妨按照html中指定的路径放好图片,css和js文件先不管。用浏览器打开这个html,就是一排按顺序显示的图片。我这里在页面中间截一个图:
可以看到,浏览器就是简单地将ul中的图片按照本身的大小一幅一幅显示出来。每一个li前面还有list的小圆点。
添加css
基本的css样式
下面我们给以上html引入css,逐步添加样式完成最终的slider。
思路就是,假设我们有5张待显示的幻灯片,也就是5个li,我们不妨将它们的父元素ul设置为5倍的屏幕宽度,然后将该ul的定位position设为relative。当需要显示某张图片的时候,我们使用jQuery或者css3动画,通过设置正确的position位置显示该图。具体的实现也不难,下面一步步进行。
先加入简单的style.css:
//去掉某些默认的内外边距 * { margin: 0; padding: 0; } //去掉list前的小黑点 ul { list-style: none; } //将包含图片的ul的position设为relative ul.img-slider { position: relative; width: 500%; overflow: hidden; } .img-slider li { width: 800px; margin-top: 25px; float: left; }
代码中写了注释,请仔细看。这里去掉了一些默认的内外边距,防止之后幻灯片定位不能处于中心。去掉list前面的黑点。实际上主要做的是:
1、首先将ul.img-slider的定位设为relative,这样后面就可以通过它的left属性来讲其左右移动,形成slide的效果;然后将ul.img-slider宽度设为500%,也就是页面宽度的5倍;最后是overflow属性,当超宽时,hidden,这样我们一次只能看到一张图片。
2、其次将.img-slider中的li宽度定为800px,并让它向左浮动。这样5张幻灯片会排成一排。
下面我们对li中的图片做一定的处理:
.img-slider img { max-width: 100%; height: auto; -moz-box-shadow:0px 0px 7px #eee; -webkit-box-shadow:0px 0px 7px #eee; box-shadow:0px 0px 7px #eee; border: 4px solid #DDD; -moz-border-radius:4px; -webkit-border-radius:4px; border-radius:4px; display: block; }
这段代码中间我用空格隔开了,空格上面是主要的,下面只不过是增加一些阴影和边框的特效罢了。不赘述。上面的两行比较重要:
max-width: 100%; height: auto;
会让图片响应式缩放,也就是说,图片的大小会随着li的大小自动放缩。这样就为我们响应式布局打下基础。
对于下面的小图也是一样:
.img-thumbnails { position: relative; } .img-thumbnails img{ max-width: 100%; height: auto; border: 5px solid #FFFFFF; -moz-box-shadow:1px 1px 7px #555; -webkit-box-shadow:1px 1px 7px #555; box-shadow:1px 1px 7px #555; cursor:pointer; display:block; opacity: 0.8; } .img-thumbnails li { position: relative; float: left; background-color: rbga(220,220,220,.5); margin-top: 5px; width: 70px; } .img-thumbnails li:hover { bottom: 10px; } .img-thumbnails li:hover img { opacity:1.0; }
我们将小图的li设为relative定位,当鼠标hover过的时候,通过设置
.img-thumbnails li:hover { bottom: 10px; }
让图片“跳”起来。同时通过透明度的改变,更加强调一下被hover中的图片。
这时候打开浏览器,大概是下面的样子:
这时候将鼠标移动到小的预览图片,已经可以跳动了,同时透明度会变为1.0突出显示。
媒体查询响应式布局
接下来我们使用媒体查询,根据屏幕的尺寸进行响应式布局。
@media (max-width: 1024px) { .img-slider li{ width: 640px; } .img-slider img { border: 2px solid #DDD; } .img-thumbnails li { width: 56px; } .img-thumbnails img { border: 2px solid #FFFFFF; } } @media (max-width: 640px) { .img-slider li { width: 20%; } .img-slider img { border: 0; } .img-thumbnails li { width: 10%; } .img-thumbnails img { border: 1px solid #FFFFFF; } }
将以上代码放在css文件的最后面,特别注意max-width大小的放置顺序,小的宽度要放在后面,不然会被覆盖,得不到我们想要的结果。
到这里,我们可以试着拉动浏览器调整宽度,感受一些这里媒体查询的响应式布局。
特别注意一下,我们希望屏幕宽度小于640px的时候(主要就是移动端),li的宽度能适应屏幕的宽度,满铺。我们在宽度小于640px的时候,将li的宽度设为20%,特别注意这个20%是相对于它的容器ul的,ul宽度为500%,再乘以20%,刚好是一个屏幕的宽度。
css到这就差不多了,我们“画蛇添足”地给图片加一个背景
.wrapper { overflow: hidden; background-image: url('../images/img1.jpg'); background-position: left top; background-size: cover; }
初始状态是利用第一张图片作为背景。提一下,background-size:cover是将背景图按照横纵比缩放到将背景完全覆盖的最小大小。
现在再来看一下,如下所示:
加入简单的js让图片滑动起来
添加点击滑动事件
这里的js十分简单,思路就是当点击小的预览图的时候,通过改变ul的left属性,让它滑动到指定的显示位置就行了。
$(document).ready(function(){ var li_img = $('.img-slider li'); for(var i=0; i<li_img.length; i++) { (function(index){ $('.img-thumbnails li:nth-child('+(index+1)+')').on('click', function(evt){ $('.wrapper').css('background-image', 'images/thumbnail/img'+(index+1)+'.jpg)'); $('.img-slider').stop().animate({left: -index*document.documentElement.clientWidth}, 500); }); })(i); } });
这里代码虽然简单,有几个细节:
1、循环中赋值事件处理函数
一定要注意,不能写成
for(var i=0; i<li_img.length; i++) { $('.img-thumbnails li:nth-child('+(i+1)+')').on('click', function(evt){ $('.wrapper').css('background-image', 'images/thumbnail/img'+(i+1)+'.jpg)'); $('.img-slider').stop().animate({left: -i*document.documentElement.clientWidth}, 500); }); }
如果这样写的话,点击的时候,每次事件处理的结果i都等于li_img.length,具体涉及闭包知识,不多说了,可查看相关文档。
2、动画的精细控制
$('.img-slider').stop().animate({left: -index*document.documentElement.clientWidth}, 500);
在开始新的动画之前,一定先调用一下stop()方法,因为每个动画都会进到一个队列中,如果在启用新的动画前不停止之前的动画,我们快速点击小图片之后,由于动画需要一定的时长,当我们停止点击的时候,动画还会按顺序播放完毕。十分奇怪!
让图片动态居中显示
接下来,为了让图片居中显示,我们动态给出外边距:
function initScreen(){ //浏览器窗口resize时回到可控初始状态 $('.wrapper').css('background-image', 'url(https://7xroh5.com1.z0.glb.clouddn.com/demo-responsiveSlider-img1.jpg)'); $('.img-slider').stop().animate({left: 0}, 500); if(window.innerWidth > 1024) { //设置 $('.img-slider li').css('margin-left', (document.documentElement.clientWidth-800)/2); $('.img-slider li').css('margin-right', (document.documentElement.clientWidth-800)/2); }else if(window.innerWidth > 640) { //设置 $('.img-slider li').css('margin-left', (document.documentElement.clientWidth-640)/2); $('.img-slider li').css('margin-right', (document.documentElement.clientWidth-640)/2); }else { $('.img-slider li').css('margin-left', 0); $('.img-slider li').css('margin-right', 0); } };
这里使用本办法查询了屏幕的宽度,也是为了配合css进行响应式布局。
左右外边距的宽度是屏幕宽度减去图片li宽度,再除以2,道理很简单,不用多说了吧?当屏幕宽度小于640px的时候,margin设为0。
//浏览器窗口resize时回到可控初始状态 $('.wrapper').css('background-image', 'url(https://7xroh5.com1.z0.glb.clouddn.com/demo-responsiveSlider-img1.jpg)'); $('.img-slider').stop().animate({left: 0}, 500);
这2条代码是为了当屏幕大小被人为拉动的时候,能够回到可控的初始状态。
因为当屏幕大小发生变动的时候,虽然元素的大小以及li的外边距会随之变化,但是,ul的left值还是根据之前的宽度计算的,会导致对不准图片。有兴趣的删掉这两句试一试。
响应窗口的伸缩变化
为了能够在屏幕被人为拉伸之后依然能够正常显示,我们加上以下的代码:
$(window).resize(function(){ initScreen(); });
每次,屏幕被resize的时候,都会调用上面的initScreen函数,重新调整外边距,同时让动画回到初始状态。
demo&download
好了,大功告成,实际上slider的实现十分简单。
本文在响应式布局上使用相对多一点的代码。也提供一种实现的方法。针对特定的情况,可以进行针对性的增删。
demo和download在这里可以下载