Javascript自定义插件slider使用(首页图片轮播)

大家或许做过(照片轮播)无限滚动图片的项目,但是,如果使用普通的滚动,当到达最后一张时,便会滚动回第一张,这是一个非常不好的用户体验。


但是如果使用不停生成img标签,过了的就移除的话,因为对DOM操作频繁,会对性能造成很大的影响。

那有木有一个方法,即能不使它回滚,又可以有很好的性能呢?

答案是有的。

我的想法是这样的:

中间那一张图片, 假如左移100%,那么当到达中间展示的时候,就使用transform右移 -100%,这样就抵消了,过了的话,100%变成200%; 同理,其他的照片一样

代码如下

Slider 使用(html):

	<div class="banner">
			<div id="bannerBody"></div>
				<div class="m-banner">
					<ul class="m-cursor">
						<li class="prev"><</li>
						<li class="cursor">1</li>
						<li class="cursor">2</li>
						<li class="cursor">3</li>
						<li class="next">></li>
					</ul>
				</div>
		</div>
	var $ = function(selector){
			return [].slice.call(document.querySelectorAll(selector));
		}

		var cursor = $('.m-cursor .cursor');
		var prev = $('.m-cursor .prev')[0];
		var next = $('.m-cursor .next')[0];



		cursor.forEach(function (cursor, index){
			cursor.addEventListener('click', function(){
				slider.nav(index);
			})
		})

		prev.addEventListener('click',function(){
			slider.prev();
		});

		next.addEventListener('click', function(){
			slider.next();
		});

		var slider = new Slider({
			     //视口容器
  				  container: document.body,
  				 // 图片列表
				  images: [
				    "./imgs/banner1.jpg",
				    "./imgs/banner2.jpg",
				    "./imgs/banner3.jpg",
				  
				  ],

				  // 是否允许拖拽
				  drag: true
		});

		// 通过监听`nav`事件来完成额外逻辑
	// --------------
	slider.on('nav', function(ev){
		var pageIndex = ev.pageIndex;
		cursor.forEach(function(cursor, index){
			if (index === pageIdnex){
				cursor.className = 'z-active';
			}else{
				cursor.className = 'slide';
			}
		})
	})

// 3s 自动轮播
	// setInterval(function(){
	// 	slider.next();
	// }, 3000);

	slider.nav(1)
//附上Slider.js
//slider.js
;(function(_){


  // 将HTML转换为节点
  function html2node(str){
    var container = document.createElement('div');
    container.innerHTML = str;
    return container.children[0];
  }


  var template = 
  	'<div class="m-slider">\
  		<div class="slide"></div>\
  		<div class="slide"></div>\
  		<div class="slide"></div>\
  	</div>';



  function Slider(opt){
  	_.extend(this, opt);

  	//节点及样式设置
  	this.container = this.container ||  document.getElementById('bannerBody');
  	this.container.style.overflow = 'hidden';

  	//组件节点
  	this.slider = this._layout.cloneNode(true);
    this.slides = [].slice.call(this.slider.querySelectorAll('.slide'));



  	//拖拽
  	this.offsetWidth = this.container.offsetWidth;
  	this.breakPoint = this.offsetWidth / 4;
  	this.pageNum = this.images.length;

  	//内部数据结构
  	this.slideIndex = 1;
  	this.pageIndex = this.pageIndex || 0;
  	this.offsetAll = this.pageIndex;
    // this.pageNum 必须传入
    // 初始化动作
  	this.container.appendChild(this.slider);
  	
    // 如果需要拖拽切换
    if(this.drag) this._initDrag(); 

  }

  _.extend(Slider.prototype, _.emitter);

  _.extend( Slider.prototype, {

  	_layout: html2node(template),

  	//直接跳转到指定页
  	 nav: function( pageIndex ){

  	 	this.pageIndex = pageIndex;
  	 	this.slideIndex = typeof this.slideIndex === 'number' ? this.slideIndex: (pageIndex+1)%3;
  	 	this.offsetAll = pageIndex;
     // this.slider.style.transition = "fadeIn";
  	 	this.slider.style.transitionDuration = '0s';

  	 	this._calcSlide();

  	 },
  	 //next
  	 next: function(){
  	 	this._step(1);
  	 },
  	 //上一页
  	 prev:function(){
  	 	this._step(-1);
  	 },

  	 //   // 单步移动
  	 _step(offset){
  	 	this.pageIndex += offset;
  	 	this.offsetAll += offset;
  	 	this.slideIndex += offset;
  	 	this.slider.style.transitionDuration = '.5s';

  	 	this._calcSlide();
  	 },
  	  // 计算Slide
    // 每个slide的left = (offsetAll + offset(1, -1)) * 100%;
    // 外层容器 (.m-slider) 的偏移 = offsetAll * 宽度
    _calcSlide: function(){
    	var slideIndex = this.slideIndex = this._normIndex(this.slideIndex, 3),
    			pageIndex = this.pageIndex = this._normIndex(this.pageIndex, this.pageNum),
    			offsetAll = this.offsetAll,
    			pageNum = this.pageNum;

    	var prevSlideIndex = this._normIndex(slideIndex -1, 3),
    		nextSlideIndex = this._normIndex(slideIndex +1, 3);

    	var slides = this.slides;
    	slides[slideIndex].style.left = (offsetAll) * 100 + '%';
    	slides[prevSlideIndex].style.left = (offsetAll -1) * 100 + '%';
    	slides[nextSlideIndex].style.left = (offsetAll +1) * 100 + '%';
      // slides[prevSlideIndex].style.animation = "fadeOut 0.5s";
      // slides[nextSlideIndex].style.animation = "fadeIn 0.5s";
    	// 容器偏移
    	this.slider.style.transform = 'translateX(' + (- offsetAll * 100) +'%) translateZ(0)';


      // 当前slide 添加 'z-active'的className
      slides.forEach(function(node){ _.delClass(node, 'z-active') })
      
    	_.addClass(slides[slideIndex], 'z-active');

    	this._onNav(this.pageIndex, this.slideIndex);

   },

     // 标准化下标
    _normIndex:  function(index, len){
    	return (len + index) % len;
    },

    // 跳转时完成的逻辑, 这里是设置图片的url
    _onNav: function( pageIndex, slideIndex){
    	var slides = this.slides;
//console.log("slideIndex:"+slideIndex+" pageIndex: "+pageIndex)
    	for(var i = -1; i<=1; i++){

    		var index = (slideIndex + i +3 ) %3;
    		var img = slides[index].querySelector('img');
    		if(!img){
    			img = document.createElement('img');
    			slides[index].appendChild(img);
    		}

    		img.src = './imgs/banner'+ (this._normIndex(pageIndex + i, this.pageNum)+1)+ '.jpg';
    	}

    	this.emit('nav', {
    		pageIndex: pageIndex,
    		slideIndex: slideIndex
    	})

    },




  //   // 拖动相关, 有兴趣的同学
  //   // ----------

    _initDrag: function(){

      this._dragInfo = {};
      this.slider.addEventListener('mousedown', this._dragstart.bind(this));
      this.slider.addEventListener('mousemove', this._dragmove.bind(this));
      this.slider.addEventListener('mouseup', this._dragend.bind(this));
      this.slider.addEventListener('mouseleave', this._dragend.bind(this));

    },

    _dragstart: function(ev){
      var dragInfo = this._dragInfo;
      dragInfo.start = {x: ev.pageX, y: ev.pageY};
    },

    _dragmove: function(ev){

      var dragInfo = this._dragInfo;
      // 如果还没有开始拖拽则退出
      if(!dragInfo.start) return;

      ev.preventDefault();
      this.slider.style.transitionDuration = '0s';

      var start = dragInfo.start;
      // 清除恼人的选区
      if (window.getSelection) {
        window.getSelection().removeAllRanges();
      } else if (window.document.selection) {
        window.document.selection.empty();
      }

      // 加translateZ 分量是为了触发硬件加速
      this.slider.style.transform = 
       'translateX(' +  (-(this.offsetWidth * this.offsetAll - ev.pageX+start.x)) + 'px) translateZ(0)'

    },

    _dragend: function( ev ){

      var dragInfo = this._dragInfo;
      if(!dragInfo.start) return;

      ev.preventDefault();
      var start = dragInfo.start;
      this._dragInfo = {};
      var pageX = ev.pageX;

      // 看走了多少距离
      var deltX = pageX - start.x;
      if( Math.abs(deltX) > this.breakPoint ){
        this._step(deltX>0? -1: 1)
      }else{
        this._step(0)
      }

    }

    
  })


  window.Slider = Slider;





})(util);


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值