资讯专栏INFORMATION COLUMN

原生js实现移动端+pc端 轮播插件

leanxi / 2773人阅读

摘要:原生写的轮播兼容移动端插件,支持轮播速度,轮播内容,轮播间隔,手势灵敏度自定义,导航圆点点击跳转手势滑动。使用说明文件包含小部分语法编写的文件,在移动端有兼容性问题,仅供于源码参考。移动端跟端开发引用文件直接下载进行引入使用。

slide.js

原生js写的轮播兼容 pc+移动端 插件,支持轮播速度,轮播内容,轮播间隔,手势灵敏度自定义,导航圆点点击跳转,手势滑动。

使用说明:slide.js文件包含小部分es6语法编写的文件,在移动端有兼容性问题,仅供于源码参考。移动端跟pc端开发引用js文件直接下载slide-es5.js进行引入使用。

html代码

必须需要设置:包裹元素的id,以及高度跟宽度

包裹元素下面需要跟随一个div,div下面是带有class属性为slide-item的任意元素

js代码:

//需要先引入插件

    
   

//第一个参数是设置了轮播的包裹元素的id,是必须参数
//第二个参数是轮播间隔,非必须参数,默认为3000ms
//第三个参数是轮播速度, 非必须参数,默认为1,数值越大轮播速度越快
//第四个参数是手指滑动灵敏度,非必须参数,默认为20,数值越大需要滑动触发的距离就越大

这是上面代码的slide Demo

废话不多说,下面实现代码跟注释说明

(function () {
let Slide = function (
    slideId = "slide",
    timeOut = 3000,
    speed = 0.1,
    d = 20
) {
    this.d = d;//滑动灵敏度
    this.timeOut = timeOut;//轮播间隔
    this.slide = document.querySelector("#slide"); //获取视窗层
    this.room = this.slide.querySelector("div"); //获取内容层
    this.imgs = [...this.slide.querySelectorAll(".slide-item")]; //轮播图元素组
    this.slideWidth = parseInt(getComputedStyle(this.slide).width); //视窗层高度
    this.slideHeight = parseInt(getComputedStyle(this.slide).height); //视窗层宽度
    this.startPoint = null; //手指触摸的起点
    this.navButtons = null; //获取到所有的导航圆点
    this.timer = null; //定时器
    this.imgIndex = 1; //当前轮播图片index
    this.prev = null; //上一个
    this.next = null; //下一个
    this.speed = -(this.slideWidth / 10 * speed); //动画速度
    this.resetCss(); //初始化css样式
    this.resetAll(); //初始化设置
    this.imgs.forEach((el) => {
        el.style.height = `${this.slideHeight}px`;
        el.style.width = `${this.slideWidth}px`;
    }); //使图片的宽度跟视窗层一样
    this.autoStart = setInterval(() => {
        this.nextItem()
    }, timeOut);
    //轮播间隔定时器

    for (let i = 0; i < this.navButtons.length; i++) {
        this.navButtons[i].onclick = this.navButtonClick.bind(this);
    } //绑定导航圆点点击事件
    //绑定触摸开始事件
    this.slide.addEventListener("touchstart", this.touchstart.bind(this));
    //绑定触摸结束事件
    this.slide.addEventListener("touchend", this.touchend.bind(this));
}
//初始化样式
Slide.prototype.resetCss = function () {
    let styleEle = document.createElement("style"); //创建style标签
    let navLeft = this.slideWidth / 2 - this.imgs.length * 9;
    let navTop = this.slideHeight / 40;
    styleEle.innerHTML += ".slide{position:relative;overflow:hidden;font-size:0;}"; //舒适化slide视窗的样式
    styleEle.innerHTML += ".slide .room{position:absolute;}"; //初始化room内容层的样式
    styleEle.innerHTML += ".slide .slide-item{display:inline-block;}"; //设置slide-item的样式为内联块级元素
    styleEle.innerHTML += `.slide .nav{padding:0 4px;list-style:none;position:absolute;font-size:0px;bottom:${navTop}px;left:${navLeft}px;text-align:center;}`;
    styleEle.innerHTML += ".navButton{display:inline-block;margin:6px 4px;background:#fff;width:8px;height:8px;-moz-border-radius:8px;border-radius:8px;cursor:pointer;box-shadow:0 0 6px #bbb;}";
    document.head.appendChild(styleEle); //插入标签
}

Slide.prototype.resetAll = function () {
    this.slide.setAttribute("class", "slide"); //给slide元素增加class属性
    this.room.setAttribute("class", "room"); //给room元素增加class属性
    this.room.style.left = `0px`; //设置room的初始距离
    this.room.style.width = `${this.slideWidth * (this.imgs.length)}px`; //设置内容层的宽度
    //创建导航圆点定位框
    let nav = document.createElement("ul");
    nav.id = "nav";
    nav.setAttribute("class", "nav");
    this.slide.appendChild(nav);

    for (let i = 0; i < this.imgs.length; i++) {
        let navButtonLi = document.createElement("li");
        navButtonLi.setAttribute("class", "navButton");
        navButtonLi.index = i + 1;
        nav.appendChild(navButtonLi);
    }
    this.navButtons = this.slide.querySelectorAll("li"); //获取所有的li节点
    this.navButtons[0].style.background = "#333"; //初始化第一个圆点的颜色
}
//切换下一个的函数
Slide.prototype.nextItem = function () {
    //清除过度定时器
    clearInterval(this.timer);
    //清除间隔播放定时器
    clearInterval(this.autoStart);
    this.timer = setInterval(() => {
        let left = parseInt(this.room.style.left);
        if (this.imgIndex < this.imgs.length) {
            if (left > (-this.slideWidth * this.imgIndex)) {
                this.room.style.left = `${parseInt(this.room.style.left)+this.speed}px`;
            } else {
                clearInterval(this.timer);
                this.room.style.left = `${-this.slideWidth*this.imgIndex}px`;
                this.navButtons[this.imgIndex - 1].style.background = "#fff";
                this.imgIndex++;
                this.navButtons[this.imgIndex - 1].style.background = "#333";
            }
        } else {
            if (left < 0) {
                this.room.style.left = `${parseInt(this.room.style.left)+(-this.speed*2)}px`;
            } else {
                clearInterval(this.timer);
                this.room.left = "0";
                this.navButtons[this.imgIndex - 1].style.background = "#fff";
                this.imgIndex = 1;
                this.navButtons[this.imgIndex - 1].style.background = "#333";
            }
        }
    }, 16.7);
    this.autoStart = setInterval(() => {
        this.nextItem()
    }, this.timeOut);
}

Slide.prototype.lastItem = function () {
    clearInterval(this.timer);
    clearInterval(this.autoStart);
    this.timer = setInterval(() => {
        let left = parseInt(this.room.style.left);
        if (this.imgIndex > 1) {
            if (left < (-this.slideWidth * (this.imgIndex - 2))) {
                this.room.style.left = `${parseInt(this.room.style.left)-this.speed}px`;
            } else {
                clearInterval(this.timer);
                this.room.style.left = `${-this.slideWidth*(this.imgIndex-2)}px`;
                this.navButtons[this.imgIndex - 1].style.background = "#fff";
                this.imgIndex--;
                this.navButtons[this.imgIndex - 1].style.background = "#333";
            }
        } else {
            if (left > -this.slideWidth * (this.imgs.length - 1)) {
                this.room.style.left = `${parseInt(this.room.style.left)+(this.speed*2)}px`;
            } else {
                clearInterval(this.timer);
                this.room.left = `${-this.slideWidth*this.imgs.length-1}px`;
                this.navButtons[this.imgIndex - 1].style.background = "#fff";
                this.imgIndex = this.imgs.length;
                this.navButtons[this.imgIndex - 1].style.background = "#333";
            }
        }
    }, 16.7);
    this.autoStart = setInterval(() => {
        this.nextItem()
    }, this.timeOut);
}
Slide.prototype.navButtonClick = function ({
    target
}) {
    clearInterval(this.autoStart);
    clearInterval(this.timer);
    this.timer = setInterval(() => {
        let left = parseInt(this.room.style.left);
        if (target.index > this.imgIndex) {
            if (left > -this.slideWidth * (target.index - 1)) {
                this.room.style.left = `${parseInt(this.room.style.left)+this.speed*(target.index-this.imgIndex)}px`;

            } else {
                clearInterval(this.timer);
                this.room.style.left = `${-(this.slideWidth)*(target.index-1)}px`;
                this.navButtonStyle(target);
            }
        } else if (target.index < this.imgIndex) {
            if (left < -this.slideWidth * (target.index - 1)) {
                this.room.style.left = `${parseInt(this.room.style.left) - this.speed * (this.imgIndex - target.index)}px`;
            } else {
                clearInterval(this.timer);
                this.room.style.left = `${(-this.slideWidth) * (target.index - 1)}px`;
                this.navButtonStyle(target);

            }
        } else {
            return false;
        }
    }, 16.7);
    this.autoStart = setInterval(() => {
        this.nextItem()
    }, this.timeOut);
}
//导航圆点点击事件
Slide.prototype.navButtonStyle = function (target) {
    target.style.background = "#333";
    this.navButtons[this.imgIndex - 1].style.background = "#fff";
    this.imgIndex = target.index;
}
//手指触摸起始触发函数
Slide.prototype.touchstart = function (e = window.event) {
    this.startPoint = e.touches[0];
}
//手指触摸结束触发函数
Slide.prototype.touchend = function (e = window.event) {
    let endPoint = e.changedTouches[0];
    let x = endPoint.clientX - this.startPoint.clientX;
    let y = endPoint.clientY - this.startPoint.clientY;
    if (Math.abs(x) > this.d) {
        if (x < 0) {
            this.nextItem();
        } else {
            this.lastItem();
        }
    }
}
this.Slide = Slide;
})();
使用说明以及源代码后续的优化,欢迎关注我的github 插件地址slide插件

欢迎评论以及留言,同时欢迎关注我的博客定时不断地更新我的文章 陈建光的博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94347.html

相关文章

  • 原生js写一个无缝轮播插件(支持vue)

    摘要:轮播图插件前言写这个插件的原因前段时间准备用加上网易云的接口,模拟网易云音乐移动端。目前主要实现了无缝轮播,自动播放,端左右按钮点击切换,移动端手势滑动切换。 轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端。因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使用UI组件。在轮播图部分,...

    MSchumi 评论0 收藏0
  • 原生js写一个无缝轮播插件(支持vue)

    摘要:轮播图插件前言写这个插件的原因前段时间准备用加上网易云的接口,模拟网易云音乐移动端。目前主要实现了无缝轮播,自动播放,端左右按钮点击切换,移动端手势滑动切换。 轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端。因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使用UI组件。在轮播图部分,...

    hatlonely 评论0 收藏0
  • 原生js写一个无缝轮播插件(支持vue)

    摘要:轮播图插件前言写这个插件的原因前段时间准备用加上网易云的接口,模拟网易云音乐移动端。目前主要实现了无缝轮播,自动播放,端左右按钮点击切换,移动端手势滑动切换。 轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端。因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使用UI组件。在轮播图部分,...

    褰辩话 评论0 收藏0
  • 移动布局与适配

    摘要:实战之微信钱包腾讯服务界面网格布局是让开发人员设计一个网格并将内容放在这些网格内。对于移动端适配,不同的公司不同的团队有不同的解决方案。栅格系统用于处理页面多终端适配的问题。 grid实战之微信钱包 腾讯服务界面 CSS3网格布局是让开发人员设计一个网格并将内容放在这些网格内。而不是使用浮动制作一个网格,实际上是你将一个元素声明为一个网格容器,并把元素内容置于网格中。 移动端页面适配—...

    Clect 评论0 收藏0
  • 2019年前学习路线

    摘要:也就是我们常见的浏览器以及内置浏览器,比如微信打开的大型移动端网页。这个以微信小程序为例,主要是微信团队基于前端基础来做的封装语法,主要的还是语法。学习路线放一下给大家。前端开发学习不是单一的,内容比较多,同样应用的场景也非常多。 近两年来,前端开发工程师越来越火了,2019年已经到来了,很多准备入行前端开发工程师的小伙伴们,不知道准备得怎么样了呢?有的朋友在想方设法的学习,争取在年后...

    cfanr 评论0 收藏0

发表评论

0条评论

leanxi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<