js轮播图小插件

昨天被提到无缝轮播图,当时忘记怎么做的了,回来后就自己做了个小插件。勿喷,谢谢!
废话不多说直接上代码!
html

<template>
  <div class="home">
      <div ref="box" style="margin-top:100px;width: 300px;height: 200px"></div>
  </div>
</template>

<script>
import Slideshow from '../utils/slideshow/index.js'

export default {
  name: 'Home',
  data() {
    return {

    }
  },
  mounted() {
    let imgArr = [
      require('../assets/01.jpg'),
      require('../assets/02.jpg'),
      require('../assets/03.jpg'),
      require('../assets/04.jpg'),
    ]
    let slideshow = new Slideshow({
      imgArr,
      // width:375,
      // isEleDots:true,
      // isBtn:true
    })
    slideshow.creatNode(this.$refs.box)

  },
}
</script>

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>Tesseract</title>
	</head>
	</head>
	<body>
		<div class="box" style="margin-top:100px;width: 300px;height: 200px"></div>
	</body>
	<script src="./slideshow/index.js"></script>
	<script type="text/javascript">
	let imgArr = [
	      './img/1.png',
	      './img/2.png',
	      './img/3.png',
	      './img/4.png',
	      './img/5.png',
	    ]
	    let slideshow = new Slideshow({
	      imgArr,
	      // width:375,
	      isEleDots:true,
	      isBtn:true
	    })
	    slideshow.creatNode(document.getElementsByClassName('box')[0])
	</script>
</html>

index.js

/**
 * option : {
   imgArr : Array , 图片数组
   width : Number||'100%' , 容器宽度
   height : Number||'100%' , 容器高度
   isEleDots : Boolean , 是否显示圆点
   isBtn : Boolean , 是否显示两侧按钮
   color : String , 颜色
}
 creatNode(node(需要插入的节点,必填))
 removeEventListener() //移除所有事件
 * */

export default class Slideshow {
    constructor(option) {
        this.imgArr = option.imgArr || []   //图片数组
        this.width = option.width || '100%'    //容器宽度
        this.height = option.height || '100%'   //容器高度
        this.isEleDots = option.isEleDots || false //是否显示圆点
        this.isBtn = option.isBtn || false //是否显示两侧按钮
        this.color = option.color || '#f17d07' //颜色
        this.TIME_DURATION = option.time || 3000   //定时器时间
        this.interval = null		//定时器
        this.index = 0			 //当前图片
        this.circle = 0			 //当前高亮圆点
        this.eleInners = null    //图片ul
        this.eleDots = null		 //圆点ul
        this.liImgs = null		 //装图片的li
        this.liDots = null		 //img节点
        this.elePrev = null		 //左边按钮
        this.eleNext = null	     //右边边按钮
        this.container = null      //容器
        this.LI_WIDTH = null	 //li宽度每次移动的距离
        this.isMobile = navigator.userAgent.match(/(iPhone|iPad|Android|ios)/i) //是否位移动端
    }

    // 创建节点
    creatNode(node) {
        if (this.imgArr.length == 0) return
        this.creatStyle()
        this.width = this.width > node.clientWidth && this.width !== '100%' ? node.clientWidth : this.width
        this.height = this.height > node.clientHeight ? node.clientHeight && this.height !== '100%' : this.height
        let width = this.width != '100%' ? this.width + 'px' : node.clientWidth + 'px'
        let height = this.height != '100%' ? this.height + 'px' : node.clientHeight + 'px'
        let imgLis = ``
        this.imgArr.forEach(item => {
            imgLis += `<li style="height:${height};width:${width}">
                          <img src="${item}" alt="" >
                       </li>
                      `
        })
        let btn = `
                    <div id="btn-prev" class="btn-ctrl">&lt;</div>
				    <div id="btn-next" class="btn-ctrl">&gt;</div>
                 `
        let div = `
                    <div class="container" id="container" style="height:${height};width:${width}">
                        ${this.isBtn ? btn : ''}
                        <ul id="inner-list" style="width: ${this.imgArr.length + 1}00%">
                             ${imgLis}
                        </ul>
                        ${this.isEleDots ? '<ul id="dot-list"></ul>' : ''}
                    </div>
		        `
        node.innerHTML = div
        this.getNode()
        //首先是克隆
        this.eleInners.appendChild(this.liImgs[0].cloneNode(true));
        if (this.isEleDots) this.creatEleDots()
        //接着定时器
        this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
        this.bindEvent()

    }

    //创建样式
    creatStyle() {
        let styleContent = `
					* {
						margin: 0px;
						padding: 0px
					}
					
					#container {
						margin: auto;
						width: 500px;
						height: 500px;
						position: relative;
						overflow: hidden;
						border-radius: 5px;
					}
					
					#inner-list {
						width: 400%;
						height: 100%;
						position: absolute;
						top: 0;
						left: 0;
					}
					
					#inner-list li {
						width: 500px;
						height: 100%;
						float: left;
					}
					
					#inner-list li img {
						width: 100%;
						height: 100%;
					}
					
					#dot-list {
						position: absolute;
						bottom: 20px;
						left: 50%;
						transform: translateX(-50%);
					}
					
					#dot-list li {
						float: left;
						display: inline-block;
						width: 20px;
						height: 20px;
						border-radius: 50%;
						line-height: 20px;
						text-align: center;
						background: #ccc;
						cursor: pointer;
						margin-right: 10px;
					}
					
					#dot-list li.cur {
						background:${this.color};
					}
					
					.btn-ctrl {
						position: absolute;
						cursor: pointer;
						top: 50%;
						font-size: 36px;
						color: ${this.color};
						font-weight: 500;
						z-index: 2;
					}
					
					#btn-prev {
						left: 0px;
					}
					
					#btn-next {
						right: 0px;
					}
		`
        let style = document.createElement('style')
        style.innerHTML = styleContent
        document.getElementsByTagName('head')[0].appendChild(style)
    }

    //接着是动画,用差值和offsetLeft值和移动的值,给一个speed让它移动
    animate(obj, targetPlace) {
        clearInterval(obj.timer);
        obj.timer = setInterval(function () {
            //判断移动的位置是向左移动还是向右移动
            var speed = obj.offsetLeft > targetPlace ? -15 : 15;
            var result = targetPlace - obj.offsetLeft;
            //只要移动的差值大于speed,那么就一直让obj.style.left 改变
            if (Math.abs(result) > Math.abs(speed)) {
                obj.style.left = obj.offsetLeft + speed + 'px'
            } else {
                //否则如果已经移动的,obj.offsetleft与要移动的位置十分接近了,
                obj.style.left = targetPlace + 'px';
                clearInterval(obj.timer);
            }
        }, 10)

    }

    //向左的autoplay
    autoplay() {
        this.index++;
        if (this.index > this.liImgs.length - 1) {
            this.eleInners.style.left = 0; //赶快跳回第一张的位置
            this.index = 1; //找到第二张图片
        }
        this.animate(this.eleInners, -this.index * this.LI_WIDTH);
        if (!this.isEleDots) return
        this.circle++;

        if (this.circle >= this.liImgs.length - 1) {
            this.circle = 0; //circle回到第一个点
        }
        for (var i = 0, len = this.liDots.length; i < len; i++) {
            this.liDots[i].className = '';

        }
        this.liDots[this.circle].className = 'cur'
    }

    //向右移动
    moveRight() {
        this.index--;
        if (this.index < 0) {
            //赶快跳回第最后一张的位置
            this.eleInners.style.left = -(this.liImgs.length - 1) * this.LI_WIDTH + 'px';
            this.index = this.liImgs.length - 2; //找到倒数第二张图片
        }
        this.animate(this.eleInners, -this.index * this.LI_WIDTH);
        if (!this.isEleDots) return
        this.circle--;
        if (this.circle < 0) {
            this.circle = this.liImgs.length - 2; //circle回到最后一个点
        }
        for (var i = 0, len = this.liDots.length; i < len; i++) {
            this.liDots[i].className = '';
        }
        this.liDots[this.circle].className = 'cur'
    }

    getNode() {
        this.eleInners = document.getElementById('inner-list')
        this.container = document.getElementById('container')
        if (this.isEleDots) {
            this.eleDots = document.getElementById('dot-list')
            this.liDots = this.eleDots.children
        }
        this.liImgs = this.eleInners.getElementsByTagName('li')
        this.elePrev = document.getElementById('btn-prev')
        this.eleNext = document.getElementById('btn-next')
        this.LI_WIDTH = this.liImgs[0].offsetWidth
    }

    //绑定事件
    bindEvent() {
        //鼠标移入,清除定时器
        this.eleInners.onmouseenter = (e) => clearInterval(this.interval)
        //鼠标移出,开启定时器
        this.eleInners.onmouseleave = (e) => {
            this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
        }
        //圆点
        if (this.isEleDots) this.eleDotsBtn()
        //两侧按钮
        if (this.isBtn) this.bilateralBtn()
        else this.pcSlidingEvent()
        if (this.isMobile) this.mobileSlidingEvent()
    }

    //生成小点点
    creatEleDots() {
        for (var i = 0, len = this.liImgs.length - 1; i < len; i++) {
            var li = document.createElement('li');
            this.eleDots.appendChild(li)
        }
        //第一个点高亮
        this.liDots[0].className = 'cur'
    }

    //圆点事件
    eleDotsBtn() {
        this.eleDots.onclick = (event) => {
            clearInterval(this.interval);
            var target = event.target;
            for (var i = 0, len = this.liDots.length; i < len; i++) {
                this.liDots[i].className = '';
                if (target == this.liDots[i]) {
                    this.circle = this.index = i
                    this.liDots[this.circle].className = 'cur'
                }
            }
            this.animate(this.eleInners, -this.index * this.LI_WIDTH);
        }
    }

    //两侧按钮
    bilateralBtn() {
        this.elePrev.onclick = () => {
            clearInterval(this.interval)
            this.moveRight();
            this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
        }
        this.eleNext.onclick = () => {
            clearInterval(this.interval)
            this.autoplay();
            this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
        }
    }

    //移动端滑动事件
    mobileSlidingEvent() {
        let start, end
        this.container.ontouchstart = (e) => start = e.touches[0].pageX
        this.container.ontouchend = (e) => {
            end = e.changedTouches[0].pageX
            let direction = end - start
            clearInterval(this.interval)
            if (direction > 80) {
                this.moveRight();
            } else if (direction < -80) {
                this.autoplay();
            }
            this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
        }
    }

    //pc滑动事件
    pcSlidingEvent() {
        this.container.onmousedown = (e) => {
            let start = e.clientX
            this.container.onmouseup = (e) => {
                let end = e.clientX
                let direction = end - start
                clearInterval(this.interval)
                if (direction > 80) {
                    this.moveRight();
                } else if (direction < -80) {
                    this.autoplay();
                }
                //这里不能加定时器了因为鼠标离开的时候会在启动定时器
                // this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
            }
            //去掉默认拖拽事件
            this.container.ondragstart = () => false
        }

    }

    removeEventListener() {
        clearInterval(this.interval)
        if (this.elePrev) this.elePrev.onclick = null
        if (this.eleNext) this.eleNext.onclick = null
        if (this.eleDots) this.eleDots.onclick = null
        this.eleInners.onmouseenter = null
        this.eleInners.onmouseleave = null
        this.container.ontouchstart = null
        this.container.ontouchend = null
        this.container.onmousedown = null
        this.container.onmouseup = null
        //恢复默认事件
        this.container.addEventListener('ondragstart', (e) => {
            e.returnValue = true
        })
    }
}

支持pc端移动端左右滑动
用法
option : {
imgArr : Array , 图片数组
width : Number||‘100%’ , 容器宽度
height : Number||‘100%’ , 容器高度
isEleDots : Boolean , 是否显示圆点
isBtn : Boolean , 是否显示两侧按钮
color : String , 颜色
}

然后直接 creatNode(node)方法就可以创建轮播图了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值