- 无需加载公用库:Swiper无需加载任何公共库(如jquery)即可运行,这保证了Swiper的轻量和运行速度。Swiper也可以在加载了公共库的环境下安全的运行,如jQuery, Zepto, jQuery Mobile等。
- 1:1的触摸滑动:Swiper默认的触摸比例为1:1,你可以通过修改Swiper的设置来改变这个比例。
- 监视器:Swiper3 增加了开启监视器的选项,有了这个功能Swiper可以在你动态改变DOM或Swiper的样式时自动重新初始化并计算所需的元素。
- 丰富的API:Swiper 拥有丰富的API,他允许你建立自己独特的分页器、导航、视差滚动、或其他精彩的效果
- 真正支持RTL(从右向左)布局:Swiper是唯一一个支持100%RTL布局的滑动插件。
- 多行slides布局:Swiper允许多行Slides布局,这样每行的slide就会较少。
- 过渡效果:增加了三种新的过渡效果:淡入、3D方块、3D流。
- 两种控制方式:现在Swiper可以用来控制其他的Swiper,甚至可以同时控制。
- 完整的导航控制:Swiper带有所有常用的导航控制器,包括分页器,切换箭头,滚动条。
- Flexbox布局:Swiper使用流行的flexbox布局,这样就解决了很多计算尺寸方面的问题。这种布局也允许用CSS来设定Slides。
- Flexbox网格(伸缩布局):你可以在Swiper初始化的时候设定slide的显示,包括每行、每列、每组数量以及他们的间距等。
- 其他的特性:Swiper3还包含了所有swiper2的牛逼功能,包括自适应、滚动反弹、抵抗反弹、loop模式、嵌套Swiper。
看了这么多Swiper的兼容、独立、可操作性等功能特性,真是移动端(现在也支持PC端的拖放事件了)开发的中利器之一,开始吸星大法学习他。
1. Swiper使用方法
a) 首先加封swiper.min.js脚本和swiper.min.css文件(废话)
b) 如果你的页面加载了jQuery.js或者zepto.js,你可以选择使用更轻便的swiper.jquery.min.js。
c) 加段html代码
d) 初始化Swiper:最好是挨着</body>标签
上示例,我用swiper.js 和 zepto.js 做了个小的电影图片切换,功能在一点一点儿的加,有缺点请大家指出来,我会虚心向大家学习:
文件有:
css 文件夹 / index.css
dist 文件夹 / css 文件夹 / swiper.min.css
/ js 文件夹 / swiper.js、zepto.min.js
/ zepto_lib / touch.js
其中只有 index.html 和 index.css 是自己写的,其他文件是第三方CSS、JS库(版本:Swiper 3.4.0,Zepto v1.1.6)。
index.html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Swiper Example from henry</title>
<link href="dist/css/swiper.min.css" rel="stylesheet" />
<link href="css/index.css" rel="stylesheet" />
<style>
.swiper-container {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="wrap">
<div id="header">
<div class="top">
<!-- 左侧logo -->
<div class="top_logo"></div>
<!-- 右侧 小导航 或 外链 -->
<div class="top_right">
<a class="link_text" href="#">APP下载</a>
<a class="link_text" href="#">关于</a>
<a class="link_text" href="#">社区</a>
</div>
</div>
<!--导航栏 tab menu list 可横向拖动,点击tab可切换页面 内容-->
<nav>
<div class="nav_inner">
<div class="nav_list swiper-container-horizontal" id="swiper-container-tab">
<div class="swiper-wrapper">
<a href="#" class="slide-a" target="_self"><span class="nav-item active-nav" data-category="-1">最新</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-2">广播</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-3">推荐</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-4">新闻</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-5">综艺</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-6">更多1</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-7">更多2</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-8">更多3</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-9">更多4</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-10">更多5</span></a>
<a href="#" class="slide-a" target="_self"><span class="nav-item" data-category="-11">END</span></a>
</div>
</div>
</div>
</nav>
</div>
<!--主体内容-->
<div id="main">
<!--内容页面 1-->
<div class="swiper-container swiper-container-h" id="tab1">
<div class="swiper-wrapper">
<div class="swiper-slide" data-hash="tab1">
<!-- tab content -->
<div class="swiper-container swiper-container-v contentFilm">
<div class="swiper-wrapper" id="contentFilmDiv">
<!-- 电影图片列表 -->
</div>
<div class="swiper-scrollbar"></div>
</div>
</div>
<!-- tab2 -->
<div class="swiper-slide" data-hash="tab2">
<!-- tab content -->
slide2
</div>
<!-- tab3 -->
<div class="swiper-slide" data-hash="tab3">
slide3
</div>
<div class="swiper-slide" data-hash="tabN">
......
</div
</div>
</div>
</div>
<div class="downloadTip" id="downloadTip" style="display: block;">
<div class="downloadBG"></div>
<div class="downloadContent">
<div class="download_LO">
<img src="./images/download_logo.png">
<div class="downTest">
<p>安装My APP</p>
<p>观看VSSS视频更流畅</p>
</div>
<a class="downloadBtn" href="#">免费安装</a>
<div class="downLoadClose" id="downLoadClose"></div>
</div>
</div>
</div>
</div>
</body>
</html>
<script src="dist/js/swiper.js"></script>
<script src="dist/js/zepto.min.js"></script>
<script src="dist/js/zepto_lib/touch.js"></script>
<script type="text/javascript">
document.ontouchmove=function(e){e.preventDefault();};
window.onload = function(){
//-----------------------------------
LoadFilms();
//-----------------------------------
//使用zepto.js里的tap 和 click 事件绑定(保证移动端和桌面端都支持点击). 注: zepto.js 提供基本功能,但tap这种的屏幕事件需要实际使用时另外加载(touch.js)
$('#downloadTip').on('tap click',function(e){e.preventDefault();});
$('.downLoadClose').on('tap click',function(e){
document.querySelector('#downloadTip').style.display = 'none';
e.preventDefault();//避免 点透
});
$('.downloadBtn').on('tap click',function(e){
window.location.href = '#';
});
};
function handleResponse(response){
var ss_html = new StringBuffer();
var ss_len = 0;
$.each(response,function(index, item){
ss_html.append('<div class=\"swiper-slide\">');
ss_html.append( '<a href=\"'+item.href+'\">');
ss_html.append( '<img class=\"swiper-lazy\" data-src=\"'+item.img+'\" alt=\"'+item.name+'\" />');
ss_html.append( '<p class=\"video_title swiper-no-swiping\">'+item.name+'</p>');
ss_html.append( '<div class=\"swiper-lazy-preloader\"></div>');
ss_html.append( '</a>');
ss_html.append('</div>');
ss_len++;
});
var contentFilmDiv = document.querySelector('#contentFilmDiv');//这里暂时用ID做的动态绑定film list,后期我感觉还得用类名做绑定(根据从服务端读取的电影列表信息,绑定到指定的tab content)
contentFilmDiv.innerHTML = ss_html.toString();
//===================================================================================
//tab menu
var swiper_init_h = {
direction: 'horizontal',
spaceBetween: 0,
speed: 500,
//longSwipesRatio : 0.5,//触发swiper所需要的最小拖动距离比例, 值越大触发Swiper所需距离越大。最大值0.5
touchAngle : 10,//允许触发拖动的角度值。默认45度,即使触摸方向不是完全水平也能拖动slide。
/*swiper可以嵌套。
nested 用于嵌套相同方向的swiper时,当切换到子swiper时停止父swiper的切换。请将子swiper的nested设置为true。由于需要在slideChangeEnd时判断作用块,因此快速滑动时这个选项无效。
在做 横向swiper 内嵌 纵向swiper 时,发现有横纵向在一起的情况下会有冲突
我这里发现了个BUG, 是有纵向时横向不能拖动了!
最初我自己想通过判断在拖动时(touchstart,touchmove)两个swiper对象的 X, Y 的拖动距离的大小作为对比得出用户是横向 还是纵向拖动,确定好了再屏蔽对应方向的swipe事件,
试了几次屏蔽总不成功,后用了swiper.js 的nested:true解决了这个问题。
*/
nested: true,
preventClicks: true,//默认为true,当swiping时阻止意外的链接点击
preventClicksPropagation: true,//阻止click冒泡。拖动Swiper时阻止click事件
hashnav: true, //URL hash link
hashnavWatchState: true,
onSlideChangeStart: function(swiper){//切换Tab导航菜单CSS
//var arrNavListItem = $('.nav_list .nav-item')||null; arrNavListItem.eq(swiper.previousIndex).removeClass('nav_on'); arrNavListItem.eq(swiper.activeIndex).addClass('nav_on');
$("#swiper-container-tab .active-nav").removeClass('active-nav');
var activeNav = $("#swiper-container-tab .slide-a").eq(swiper.activeIndex).addClass('active-nav');
}
};
//film list (tab content 里的 电影列表swiper事件参数设置)
var swiper_init_v = {
scrollbar: '.swiper-scrollbar',
direction: 'vertical',
spaceBetween : 0, //slider 与 slider 之间的间隔距离
//preventClicks: true,//默认为true,当swiping时阻止意外的链接点击
preventClicksPropagation: true,//阻止click冒泡。拖动Swiper时阻止click事件
slidesPerView: 'auto',
watchSlidesVisibility: true,
mousewheelControl: true,
grabCursor : true,
freeMode: true,
//autoHeight: true, //高度随内容变化
preloadImages:false,
//updateOnImagesReady: true,//当所有的内嵌图像(img标签)加载完成后Swiper会重新初始化。使用此选项需要先开启preloadImages: true
//图片延迟加载 功能
lazyLoading: true,// Enable lazy loading
//lazyLoadingInPrevNext: true,
lazyLoadingOnTransitionStart: true, //激发没有加载的图片加载
lazyLoadingInPrevNextAmount: 4, //提前加载图片的数量,没感觉到这里的数量有变化
onLazyImageLoad: function(swiper, slide, image){
//alert('延迟加载图片');
//console.log(swiper);//Swiper实例
//console.log(slide);//哪个slide里面的图片在加载
//console.log(image);//哪个图片在加载
/*
//一开始自己计算容器调试了,为了延迟加载图片后更新容器的尺寸,后发现swiper.js有自己的更新方法 swiper.updateSlidesSize();
contentFilmDiv = document.querySelector('#contentFilmDiv'); var ss_h = mCss(contentFilmDiv.querySelectorAll('.swiper-slide')[0],'height');
mCss(contentFilmDiv,'height',ss_h*(ss_len/2+2)); */ }, onLazyImageReady: function(swiper){
//延迟加载图片后更新容器的尺寸
swiper.updateContainerSize();
swiper.updateSlidesSize();
}
};
var swiperV = new Swiper('.swiper-container-v', swiper_init_v);//创建film list (direction: vertical)的swiper
var swiperH = new Swiper('.swiper-container-h', swiper_init_h);//创建tab content (direction: horizontal)的swiper
//tab menu
var swiperTab = new Swiper('#swiper-container-tab', {
watchSlidesProgress: true, //这两个属性是为了与 tab menu 同步切换用的
watchSlidesVisibility: true,
slideClass: 'slide-a', //这里用自定义的类 slide-a 取代了 slide的默认类 .slide (swiper.js还是挺人性化的)
slidesPerView: 1, //一次显示一个slide content 这是针对 tab content (direction: horizontal)的
grabCursor : true,
freeMode: true, //tab menu 电影分类 横向列表,分类多了超宽时,可自由拖动 onTap: function(swiper, e){//swiper 自己定义的tap事件
if(swiper.clickedIndex!=swiperH.activeIndex) {//加个判断,避免重复点击同一tab menu
swiperH.slideTo(swiper.clickedIndex);//根据当前点击有Tab index切换 内容显示区
}
else {
return;
}
}
}); }
//用JSONP方式从其它网站获取JSON数据信息
function hInitJSONP(src){
var script = document.createElement("script");
script.src = src;
document.body.insertBefore(script, document.body.firstChild);
}
function LoadFilms(){
//从远程、非同域的服务器 加载 b.json 文件
hInitJSONP("http://www.xxx.com/json/b.json?callback=handleResponse"); //注:这里的URL是假的,我是想试一试JSONP的,想要真的自己找个服务器和域名/IP 试
/*我在服务端加了个静态的json文件保存film list的内容信息,内容大致如下:(内容不多,挺简单的)
handleResponse([
{ name:'足球专辑', img:'./images/1.jpg', href:"m-video.html" },
{ name:'流星时代', img:'./images/2.jpg', href:"m-video.html" },
{ name:'电视热剧', img:'./images/3.jpg', href:"m-video.html" },
{ name:'最新影片', img:'./images/4.jpg', href:"m-video.html" },
{ name:'2016中国', img:'./images/5.jpg', href:"m-video.html" },
{ name:'LiveShow', img:'./images/6.jpg', href:"m-video.html" },
{ name:'美少女', img:'./images/7.jpg', href:"m-video.html" },
{ ...... }
]);
*/
}//end function
</script>
<script>
//用于拼接string串的,比用 加号 "+" 拼接string串效率要高
function StringBuffer(){this._string = new Array;}
StringBuffer.prototype.append = function(str){this._string.push(str);};
StringBuffer.prototype.toString = function(){return this._string.join("");};
/*
用于处理CSS属性的读 和 写 的通用函数
读:两个参数mCss(element,attr) 获取当前元素对应的attr样式 返回值 number
写:三个参数mCss(element,attr,val) 设置当前元素对应的attr样式,不用加单位(px、deg、无单位)
*/
function mCss(element, attr , val){
if(attr=='scale'|| attr=='rotate'|| attr=='rotateX'|| attr=='rotateY'|| attr=='rotateZ'|| attr=='scaleX'|| attr=='scaleY'|| attr=='translateY'|| attr=='translateX'|| attr=='translateZ'){
return setTransform(element, attr , val);
}
if(arguments.length == 2){
var val = element.currentStyle?element.currentStyle[attr]:getComputedStyle(element)[attr];
if(attr=='opacity'){
val = Math.round(val*100);
}
return parseFloat(val);
} else {
switch(attr){
case 'width':
case 'height':
case 'paddingLeft':
case 'paddingTop':
case 'paddingRight':
case 'paddingBottom':
case 'borderWidth':
case 'borderLeftWidth':
case 'borderRightWidth':
case 'borderTopWidth':
case 'borderBottomWidth':
val = val < 0 ? 0 : val;
case 'left':
case 'top':
case 'marginLeft':
case 'marginTop':
case 'marginRight':
case 'marginBottom':
element.style[attr] = val +"px";
break;
case 'opacity':
element.style.filter= "alpha(opacity:"+val+")";
element.style.opacity= val/100;
break;
default:
element.style[attr]=val;
}
}
}
function setTransform(element,attr,val){
if(!element["transform"]){
element["transform"] = {};
}
if(typeof val == "undefined"){
val = element["transform"][attr];
if(typeof val == "undefined"){
val = 0;
element["transform"][attr] = 0;
}
return val;
} else {
var str = "";
element["transform"][attr] = val;
for(var s in element["transform"]) {
switch(s){
case 'rotate':
case 'rotateX':
case 'rotateY':
case 'rotateZ':
str += s+"("+element["transform"][s]+"deg) ";
break;
case 'translateX':
case 'translateY':
case 'translateZ':
str += s+"("+element["transform"][s]+"px) ";
break;
default:
str += s+"("+element["transform"][s]+") ";
}
}
element.style.MozTransform = element.style.msTransform = element.style.WebkitTransform = element.style.transform = str;
}
}
</script>
index.css的代码:
@-ms-viewport {
width: device-width;
}
address, caption, cite, code, dfn, em, strong, th, var {
font-style: normal;
font-weight: normal;
}
/* clearfix */
.clearfix:before, .clearfix:after {
content:"";
display:table;
}
.clearfix:after{
clear:both;
overflow:hidden;
}
.clearfix{
zoom:1;
}
img {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
ol, ul {
list-style: none;
}
html {
height: 100%;
font-size: 100%; background:#f7f7f7;
}
body {
position: relative;
background-color: #fff;
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
-ms-touch-action: none;
font-family: Arial, Helvetica, sans-serif;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
font-size: 14px;
}
#wrap{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
#header {
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100%;
}
#header .top {
position: relative;
background: #68c5ff;
color: #fff;
line-height: 2.75rem;
height: 2.75rem;
width: 100%;
display: -webkit-box;
display: box;
-webkit-box-pack: start;
box-pack: start;
-webkit-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#header .top_logo {
width: 79.5px;
height: 100%;
margin-left: 10px;
background-image: url("../images/header_logo.png");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
#header .top_right {
position: absolute;
right: 0;
top: 0;
}
#header .top_center {
-webkit-box-flex: 1;
}
#header .link_text {
margin-right: 10px;
font-size: 14px;
font-weight: bold;
color: white;
}
#header .nav_inner {
overflow: hidden;
/*
overflow-x: scroll;
overflow-y: hidden;
*/
-webkit-overflow-scrolling: touch;
-moz-overflow-scrolling: touch;
background-color: #f7f7f7;
border-bottom: 1px solid #d2d2d2;
height: 34px;
}
#header .nav_list {
white-space: nowrap;
}
#header .nav_list a.slide-a {
white-space: nowrap;
display: inline-block;
padding: 0 10px;
color: #6a7989;
text-decoration: none;
font-size: 13px;
height: 27px;
line-height: 26px;
margin: 5px 0px 5px 5px;
}
#header .nav_list .nav_on, #header .nav_list .active-nav {
border-bottom: 2px solid #1daffc;
color: #1daffc;
}
.selected {
color: #68c5ff;
}
.selected:after {
position: absolute;
bottom: 0px;
left: 0px;
content: "";
width: 100%;
height: 2px;
margin: auto;
/*border-radius: 2px;*/
background-color: #68c5ff;
background-repeat: repeat-x;
}
#main {
position: absolute;
top: 79px;
right: 0;
left: 0;
bottom: 0;
overflow: hidden;
}
.contentFilm{ /*swiper-container*/
position:absolute;
top: 5px;
right: 0px;
left: 0;
bottom: 0; /*50px;*/
}
.contentFilm>.swiper-wrapper{
position: relative;
display: -webkit-block;
display: -moz-block;
display: -ms-block;
display: -webkit-block;
display: block;
width: 100%; max-width:100%;
height: auto;
}
.contentFilm .swiper-slide{
width: 50%;
height: auto;
float: left;
box-sizing: border-box;
margin-bottom: 5px;
}
.contentFilm .swiper-slide a {
display: block;
margin-left: 2px;
}
.contentFilm .swiper-slide img {
display: inline-block;
width: 100%;
background-position:center center;
background-size: cover;
}
.contentFilm>.loading {
display: none;
text-align: center;
line-height: 24px;
color: #999;
padding: 10px 0;
}
#footer {
position: absolute;
right; 0;
bottom: 0;
left: 0;
width:100%;
overflow: auto;
}
#footer .copyright {
position: relative;
border-top: 1px solid #d2d2d2;
background-color: #f7f7f7;
height: 50px;
width: 100%;
text-align: center;
font-size: 10px;
color: #5b5b5b;
}
#footer .crt {
margin: 6px auto;
}
#downloadTip {
position: fixed;
bottom: 0px;
width: 100%;
height: 45px;
display: none;
max-width: 640px;
z-index: 999;
}
#downloadTip .downloadBG {
position: absolute;
width: 100%;
height: 100%;
opacity: 0.6;
background-color: black;
}
#downloadTip .downloadContent {
position: relative;
height: 45px;
line-height: 45px;
vertical-align: middle;
width: 100%;
}
#downloadTip .downLoadClose {
float: left;
width: 12px;
height: 20px;
margin-left: 10px;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url("../images/close_btn.png");
position: absolute;
right: 5px;
top: 1px;
}
#downloadTip .downloadLogo {
width: 158.5px;
float: left;
height: 100%;
margin-left: 10px;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-image: url("../images/download_logo.png");
}
#downloadTip .downloadBtn {
position: absolute;
right: 33px;
top: 9.5px;
width: 75px;
height: 26px;
line-height: 26px;
text-align: center;
border-radius: 20px;
background-color: white;
font-size: 12px;
color: #5b5b5b;
}
#downloadTip .download_LO img {
WIDTH: 38px;
float: left;
}
#downloadTip .download_LO {
padding: 7px;
color: #fff;
display: inline-block;
}
#downloadTip .downTest {
float: left;
font-size: 0.75rem;
line-height: 17px;
}