您的位置:首页 > Web前端 > JavaScript

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

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

但是如果使用不停生成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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript 轮播 拖拽