移动滑动组件学习

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" />
<meta name="apple-touch-fullscreen" content="YES" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<style>
	body{
		margin: 0;
		padding: 0;
		background: #333;
		overflow: hidden;
	}
	li,ul{
		list-style: none;
		margin: 0;
		padding: 0;
		height: 100%;
		overflow: hidden;
	}
	/* 使得图片居中 webkit-box */
	li{
		position: absolute;
		display: -webkit-box;
		-webkit-box-pack: center;
		-webkit-box-align: center;
        -webkit-backface-visibility:hidden;
	}
	li img {
		max-width: 100%;
		max-height: 100%;
	}
	/* 隐藏画布外的内容 */
	#canvas{
		height: 100%;
		width: 100%;
		overflow: hidden;
	}
</style>
</head>
<body>
	<!-- 外层画布 -->
	<div id="canvas"></div>

	<script type="text/javascript">
		//所有的数据
		var list = [{
			height: 950,
			width: 800,
			img: "imgs/1.jpg"
		},
		{
			height: 1187,
			width: 900,
			img: "imgs/2.jpg"
		},
		{
			height: 766,
			width: 980,
			img: "imgs/3.jpg"
		},
		{
			height: 754,
			width: 980,
			img: "imgs/4.jpg"
		},
		{
			height: 493,
			img: "imgs/5.jpg",
			width: 750
		},
		{
			height: 500,
			img: "imgs/6.jpg",
			width: 750
		},
		{	
			height: 600,
			img: "imgs/7.jpg",
			width: 400
		}];

		//构造函数
		function Slider(opts){
			//构造函数需要的参数
			this.wrap = opts.dom;
			this.list = opts.list;
			//构造三步奏
			this.init();
			this.renderDOM();
			this.bindDOM();
		}

		//第一步 -- 初始化
		Slider.prototype.init = function() {
			//设定窗口比率
			this.radio = window.innerHeight/window.innerWidth;
			//设定一页的宽度
			this.scaleW = window.innerWidth;
			//设定初始的索引值
			this.idx = 0;
		};

		//第二步 -- 根据数据渲染DOM
		Slider.prototype.renderDOM = function(){
			var wrap = this.wrap;
			var data = this.list;
			var len = data.length;

			this.outer = document.createElement('ul');
			//根据元素的
			for(var i = 0; i < len; i++){
				var li = document.createElement('li');
				var item = data[i];
				li.style.width = window.innerWidth +'px';
				li.style.webkitTransform = 'translate3d('+ i*this.scaleW +'px, 0, 0)';
				if(item){
					//根据窗口的比例与图片的比例来确定
					//图片是根据宽度来等比缩放还是根据高度来等比缩放
					if(item['height']/item['width'] > this.radio){
						li.innerHTML = '<img height="'+ window.innerHeight +'" src="'+ item['img'] +'">';
					}else{
						li.innerHTML = '<img width="'+ window.innerWidth +'" src="'+ item['img'] +'">';
					}
				}
				this.outer.appendChild(li);
			}

			//UL的宽度和画布宽度一致
			this.outer.style.cssText = 'width:' + this.scaleW +'px';

			wrap.style.height = window.innerHeight + 'px';
			wrap.appendChild(this.outer);
		};

		Slider.prototype.goIndex = function(n){
			var idx = this.idx;
			var lis = this.outer.getElementsByTagName('li');
			var len = lis.length;
			var cidx;

			//如果传数字 2,3 之类可以使得直接滑动到该索引
			if(typeof n == 'number'){
				cidx = idx;
			//如果是传字符则为索引的变化
			}else if(typeof n == 'string'){
				cidx = idx + n*1;
			}

			//当索引右超出
			if(cidx > len-1){
				cidx = len - 1;
			//当索引左超出	
			}else if(cidx < 0){
				cidx = 0;
			}

			//保留当前索引值
			this.idx = cidx;

			//改变过渡的方式,从无动画变为有动画
			lis[cidx].style.webkitTransition = '-webkit-transform 0.2s ease-out';
			lis[cidx-1] && (lis[cidx-1].style.webkitTransition = '-webkit-transform 0.2s ease-out');
			lis[cidx+1] && (lis[cidx+1].style.webkitTransition = '-webkit-transform 0.2s ease-out');

			//改变动画后所应该的位移值
			lis[cidx].style.webkitTransform = 'translate3d(0, 0, 0)';
			lis[cidx-1] && (lis[cidx-1].style.webkitTransform = 'translate3d(-'+ this.scaleW +'px, 0, 0)');
			lis[cidx+1] && (lis[cidx+1].style.webkitTransform = 'translate3d('+ this.scaleW +'px, 0, 0)');
		};

		//第三步 -- 绑定 DOM 事件
		Slider.prototype.bindDOM = function(){
			var self = this;
			var scaleW = self.scaleW;
			var outer = self.outer;
			var len = self.list.length;

			//手指按下的处理事件
			var startHandler = function(evt){

				//记录刚刚开始按下的时间
				self.startTime = new Date() * 1;

				//记录手指按下的坐标
				self.startX = evt.touches[0].pageX;

				//清除偏移量
				self.offsetX = 0;

				//事件对象
				var target = evt.target;
				while(target.nodeName != 'LI' && target.nodeName != 'BODY'){
					target = target.parentNode;
				}
				self.target = target;

			};

			//手指移动的处理事件
			var moveHandler = function(evt){
				//兼容chrome android,阻止浏览器默认行为
				evt.preventDefault();

				//计算手指的偏移量
				self.offsetX = evt.targetTouches[0].pageX - self.startX;

				var lis = outer.getElementsByTagName('li');
				//起始索引
				var i = self.idx - 1;
				//结束索引
				var m = i + 3;

				//最小化改变DOM属性
				for(i; i < m; i++){
					lis[i] && (lis[i].style.webkitTransition = '-webkit-transform 0s ease-out');
					lis[i] && (lis[i].style.webkitTransform = 'translate3d('+ ((i-self.idx)*self.scaleW + self.offsetX) +'px, 0, 0)');
				}
			};

			//手指抬起的处理事件
			var endHandler = function(evt){
				evt.preventDefault();

				//边界就翻页值
				var boundary = scaleW/6;

				//手指抬起的时间值
				var endTime = new Date() * 1;

				//所有列表项
				var lis = outer.getElementsByTagName('li');

				//当手指移动时间超过300ms 的时候,按位移算
				if(endTime - self.startTime > 300){
					if(self.offsetX >= boundary){
						self.goIndex('-1');
					}else if(self.offsetX < 0 && self.offsetX < -boundary){
						self.goIndex('+1');
					}else{
						self.goIndex('0');
					}
				}else{
					//优化
					//快速移动也能使得翻页
					if(self.offsetX > 50){
						self.goIndex('-1');
					}else if(self.offsetX < -50){
						self.goIndex('+1');
					}else{
						self.goIndex('0');
					}
				}
			};

			//绑定事件
			outer.addEventListener('touchstart', startHandler);
			outer.addEventListener('touchmove', moveHandler);
			outer.addEventListener('touchend', endHandler);
		};

		//初始化Slider 实例
		new Slider({
			dom : document.getElementById('canvas'),
			list : list
		});
	</script>
</body>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值