单页效果-切屏原理以及简单插件实现
2016-12-18 16:47

   页面中单页切屏的效果在做宣传的时候是常用的一个效果,无论是在PC端还是在移动端,它无意都是一个很不错的宣传页的架构。今天我们就探讨一下切屏功能的原理。

 首先分析切屏插件的结构,切屏就是当前只显示一屏内容,当点击列表或者滚动鼠标滚轮时切换到下一屏内容或上一屏内容,每一屏的内容中可能有动画或者特效,这些插件不负责实现,由使用这根据特效需求自己实现,插件只提供在一屏内容开始切换时的回调函数接口,和一屏内容切换完成时的回调函数接口。

 其实切屏插件就是图片轮播插件中的全屏轮播,你可以使用swiper插件(这个插件太大,用起来麻烦)。

<div class='container'>
    <div>first page</div>
    <div>second page</div>
    ....
</div>

下面来一张自己画的原理图

slide.png

按照这个原理图的布局,要切屏,我们只需要实现inner Div的位移就可以了。

下面我们采用jquery的插件写法,这里写的是一个初学者级别的插件,是为了让大家学习基础的插件写作形式。其中有很多欠缺的地方,高手们也不用嗤之以鼻,这些代码有问题,但是是可以正常运行,最重要的是初学者能看懂,如果上来就弄一些非常晦涩的写法,再把jquery抛弃了,我相信会很难看懂的,比如jquery的源码,想要看懂就需要有一定的功底才可。

$.fn.screen=function(options){
		before:[],
		after:[]
//这里简化后就两个参数,一个是切换前回调函数的数组,after是切屏后回调函数的数组。
		},options);
  var _=this;
 //得到调用方法的jquery对象,也就是container元素。
			
  $('body').css({margin:'0px',padding:'0px'});
//去除body的默认padding和margin。
  var w=document.documentElement.clientWidth,
	 h=document.documentElement.clientHeight;
//得到屏幕的宽高,这里要注意的是这里使用了一下单var形式
  _.css({width:w,height:h,overflow:'hidden',position:'relative'});
  var ch=_.children('div');
    _.empty();
    //创建用于移动的内部div
  var _i=$('<div></div>')
	.css({position:'absolute',left:'0',top:'0',width:'100%',height:'100%'});
	_i.appendTo(_);
//将用于移动的div添加到container容器中。
	ch.css({width:'100%',height:'100%'}).appendTo(_i);
//将各屏的内容添加到移动div中。
//到这里全屏显示的基本结构就算搭建完成了。
	......
	
};

插件中首先初始化为我们需要的结构,添加上合适的css样式。

下面我们就需要定义一个方法来实现inner对象的移动来实现切屏。

//切屏的方法实现
var currentPage=0;
//记录当前是第几屏的内容,回调函数的执行也要靠这个参数识别要执行哪个回调函数。
var lg=_i.children('div').length;
//记录一共有多少屏内容。
var sht=_i.children('div').outerHeight();
//得到屏内容的高度。也就是每次要切屏时div向上向下移动的量。
var flag=true;
//如果切屏正在进行中,则不响应滚轮滑动时间。
function slide(n){
//n是1就向下切屏,n是-1就向下切屏。
			
    if(!flag){return;}
//如果正在切换中,则返回,不做处理。
     flag=false;
    if(n>0&&currentPage<(lg-1)){
//向下切屏时,如果不是最后一屏则执行切屏动作。
//这个lg-1是因为数组是从0计数的,所以个数要-1.
        if(set.before[currentPage]){
	    set.before[currentPage]();
//这个是切屏前的回调函数执行,比如可以停止当前页面的动画,然后再切屏。
         }
        currentPage++;
//注意对当前屏数的加减操作实在执行前后动画的中间进行的。
				
       _i.animate({top:-sht*currentPage},'slow',function(){
//这个就是动画回调函数,在这里要执行切屏完成后的回调函数。
            if(set.after[currentPage]){
//如果有这个对应屏的回调函数,则执行这个回调函数。
	        set.after[currentPage]();
            }
	        flag=true;
//切屏动作执行完后,改变flag为true以便可以继续切屏。
            });
     }else{
	if(n<0&&currentPage>0){
//向上切屏时,如果不是第一屏则执行切屏动作。
	    if(set.before[currentPage]){
	        set.before[currentPage]();
//这个是切屏前的回调函数执行,比如可以停止当前页面的动画,然后再切屏。
	    }
	   currentPage--;
	   _i.animate({top:-sht*currentPage},'slow',function(){
	        if(set.after[currentPage]){
	       //意思同上。
	            set.after[currentPage]();
		}
		flag=true;
		});
	}else{
		flag=true;
//如果没执行动画,要把flag置为true;不然flag后在不能切换时一直变为false。
	      }
	}
}

这个切屏方法注释的已经很清楚了,通过传入的的页数,调用animate动画来让inner移动到相应的位置(注意:这里可以改成100%之类的百分比位置,就可以达到自适应的功能)。并且在执行之前先执行对应的切屏前回调,动画执行完毕后再执行相应的切屏后回调。

这里的回调参数是一个数组,是为了每一屏对应一个回调函数进行处理,你可以设置为一个回调函数,然后传递当前的屏数。

像下面这样

set.before(currentPage);
set.after(currentPage);

回调函数根据当前的屏数进行相应的回调处理。

最后我们需要给这个container添加事件绑定

var wheelname=navigator.userAgent.indexOf("Firefox")>0?"DOMMouseScroll":"mousewheel";
_.bind(wheelname,function(){
	var evt=window.event||arguments.callee.caller.arguments[0];
	var countV=0;
	if(evt.wheelDelta){
		countV=Math.floor(evt.wheelDelta/120)*60;
	}
	else if(evt.detail){
		countV=-Math.floor(evt.detail/3)*60;
	}
//得到鼠标滚动的值。这一块得用兼容,因为除了火狐,其他浏览器的滚轮时间还得兼容一下。
			
	if(countV<0){
		slide(1);
	}else{
		slide(-1);
	}//执行滚轮动画事件。
});

通过上面的代码,绑定上鼠标滚轮事件,这里面用到了mousewheel的兼容,你可以点击这里查看滚轮兼容详情

事件中调用slide方法来实现切屏效果。到这里这个单页插件就算完成了,他拥有基本的功能,属于初级插件。重要的是要明白其原理和基础的插件写法。你可以把它改造成你需要的,添加一些你需要的功能。

想要看效果的点击这里查看单页切换demo,支持手机端的滑动切换(这个代码是我后加上去的)。

延伸语:

   单页应用的html结构有很多种,你可以设置子元素为absolute定位,通过移动单个子元素来实现单页的切换效果,这个可以让单页循环切换。上面的代码是不行的,但是稍加改造也是可以的:中初始化的时候将子元素的顺序改为4-1-2-3,inner的top为-100%;然后向上切屏时,先动画移动到-200%,然后将4添加到1后面,在css设置为-100%;就可以实现循环切换了。你可以自己试着改造实现。

原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(5743)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1