原生JavaScript实现图片切换

原生JavaScript实现图片切换效果

效果:
原生JavaScript实现图片切换_第1张图片

html布局``

    <div class="slideshow">
        <!-- 图片区域 -->
        <div class="contentImg">
            <input type="image" src="img/prev.png" class="prev">
            <input type="image" src="img/next.png" class="next">
            <span id="countBtn">
                1/5
            </span>
        </div>
        <!-- 按钮区域 -->
        <div class="btns">
            <input type="button" class="circulation" value="循环状态">
            <input type="button" class="no_circulation" value="非循环状态">
        </div>
    </div>

css样式

body{
    margin: 0;
    padding: 0;
}
.slideshow{
    height:445px;
    width:650px;px
    margin:150px auto 0; /*设置主盒子居中离上边距150px*/
}
.contentImg{
    position: relative;
    height:400px;
    width: 650px;
    background-image: url(../img/a1.jpg);
    background-size: 100%; /*背景图片适应盒子大小*/
    transition: 2s; /*过渡时间变为2s*/
}
.contentImg input{
    height:60px;
    width:60px;
    top: 175px;
    position: absolute;
    outline: none; /*清除input框获取焦点的默认蓝色边框*/
}
.contentImg .prev{
    left: 10px;
}
.contentImg .next{
    right: 10px;
}
#countBtn{
    display: block; /*转换为块元素*/
    position:absolute;
    height: 28px;
    width:100px;
    border-radius: 14px;
    background-image:url(../img/backBotton.png);
    background-repeat: no-repeat;
    background-position-x: -5px; /*背景图片沿x轴偏移-5像素*/
    bottom: 10px;
    left: 50%;
    margin-left:-50px;
    text-align: center;
    line-height: 28px;
    font-size: 16px;
    font-weight: 600;
    color: white;
}
.btns{
    width:100%;
    text-align: center;
    margin-top: 15px;
}
.btns input{
    width: 190px;
    height: 30px;
    color: white;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    outline: none;
    background: #2164f3;
    border-radius: 10px;
    border: none;
}

布局完成!此时效果图是这样的

原生JavaScript实现图片切换_第2张图片
对于css,html这里不做过多讨论,比较陌生的地方已经加上注释了
下面的功能我们用JavaScript来实现他

接下来就是最重要的JavaScript代码,以下用两种不同的写法来实现这个功能

第一种,比较普遍的demo写法

第一步.把元素获取到

    var img = document.getElementsByClassName("contentImg")[0], //获取图片
        prev = document.getElementsByClassName("prev")[0], // 获取上一张的按钮
        next = document.getElementsByClassName("next")[0],//获取下一张的按钮
        span = document.getElementById("countBtn"), // 获取当前图片计数
        circulationNode = document.getElementsByClassName("circulation")[0],//获取循环按钮
        no_circulationNode = document.getElementsByClassName("no_circulation")[0],//获取非循环按钮

第二步.创建一个数组用于保存图片的路径

var imgArr = ["url(img/a1.jpg)", "url(img/a2.jpg)", "url(img/a3.jpg)", "url(img/a4.jpg)", "url(img/a5.jpg)"],//建立图片路径的数组

第三步.创建一些优化效率与判断是否处于循环与非循环状态

        var len = imgArr.length - 1,
        temp1 = circulationNode.style,
        temp2 = no_circulationNode.style,
        imgBg = img.style,//优化效率
        index = 0,//建立一个索引
        bool = true; //加锁  初始化为可循环

第四步.给左边的按钮添加点击事件 也就是当点击上一张的时候的事件
这里我的做法是通过改变下标的索引把图片的背景切换成不同的图片

    prev.onclick = function () {
		
    }

首先当点击上一张的时候,索引 index -1

index--;

再判断当前是否处于加锁状态,也就是判断是不是循环播放

if(bool){   //判断是否处于循环状态 
	if(index<0){    //判断是否到了第一张图片
          idnex = len;  //让下一张的索引变为最后一张
    }else{   //否则
          index = index;    //正常运转
    }
}else{  //如果不处于循环状态
	if(index<0){  //判断是否到了第一张图片
    	idnex = 0;  //让下一张图片的索引变为第一张
     }else{  //否则
 		 index = index;    //正常运转
     }
}

上面代码偶合度很高,下面用三目运算符简化一下
ps:三目运算符原理

var a = 10;
b = a < 5 ? 10 : 5;

这里的意思分步骤讲解一下:
首先 a < 5 ?
这段代码意思为判断 a < 5 吗?
10 : 5 这里意思是,当判断a < 5的两种情况
连起来读的意思为:
a < 5 吗?如果小与 那么 a = 10 ,如果不小于 a = 5;
三目运算符很符合我们上面判断是否加锁,是否到了第一张图片,给出对应的情况

bool ? (index = index < 0 ? len : index) : (index = index < 0 ? 0 : index);

简化之后只需要一行代码即可写完,是不是很神奇?

第五步,拿到了索引,接下来需要改变背景图片

imgBg.backgroundImage = `${imgArr[index]}`;

上面imgArr[index]的值就是图片路径的数组内不同索引对应的图片路径
我们只需要把img的背景图片改变成对应的路径即可

第六步,将计算当前是第几张图片的元素更新成对应的数字

span.innerHTML = (index + 1) + "/" + (len + 1);

这里运用了文档碎片,拼接了span元素的内容
ps:文档碎片
首先我们看正常的innerHTML是等于一个字符串的
但是我们需要更新索引值来求得当前是第几张图片,和总共的图片数量
数组是从0开始,但没有第0张图片,所以index的值需要加一
而number类型加上 "/"这个字符串的时候,就会变成一个字符串类型
而len 是图片数组的长度减1,所以只要加上1即可求出图片总个数
最后输出到span元素完成计数功能

打包以上代码

    prev.onclick = function () {
        index--;
        bool ? (index = index < 0 ? len : index) : (index = index < 0 ? 0 : index);
        imgBg.backgroundImage = `${imgArr[index]}`; //改变成对应图片的路径
        span.innerHTML = (index + 1) + "/" + (len + 1); //拿到当前图片的位置
   }

这样就实现了一个点击按钮切换上一张的功能

同理,点击按钮切换到下一张

    next.onclick = function () {
        index++;
        bool ? (index = index > len ? 0 : index) : (index = index > len ? len : index);
        //三目运算,参考同上
        imgBg.backgroundImage = `${imgArr[index]}`;//改变成对应图片的路径
        span.innerHTML = (index + 1) + "/" + (len + 1); //拿到当前图片的位置
    }

不过多解释了,参考切换上一张的功能

第七步,变换循环与非循环状态

功能说明,当处于循环状态时,在第一张图片点击切换到上一张会直接切换到最后一张,
在最后一张点击切换到下一张的时候会切换到第一张,这是循环状态

非循环状态 当在第一张图片点击切换到上一张,无效,还是保持在第一张
最后一张同理

给按钮添加事件,让他们可以切换状态

    //改变成循环模式的按钮
    circulationNode.onclick = function () {
        bool = true;
        temp1.background = 'yellowgreen';  //改变对应按钮的背景颜色
        temp2.background = '#2164f3';
    }

最主要的是改变bool的值,当bool为true的时候,是可循环,为false为不可循环

    no_circulationNode.onclick = function () {
        bool = false;
        temp1.background = '#2164f3';
        temp2.background = 'yellowgreen';
    }

功能到这就差不多全部实现了,下面用一个定时器优化一下,让他每隔5秒自动切换一次


    //定时器->每隔5秒钟自动更换一次图片
    var timer = setInterval(function () {
        //调用一次下一张的点击事件
        index++;
        bool ? (index = index > len ? 0 : index) : (index = index > len ? len : index);
        imgBg.backgroundImage = `${imgArr[index]}`;//改变成对应图片的路径
        span.innerHTML = (index + 1) + "/" + (len + 1); //拿到当前图片的位置
    }, 5000);

其实就是每隔5s调用一次点击下一张图片的时候的事件

所有代码如下

(function () {
    var img = document.getElementsByClassName("contentImg")[0], //获取图片
        prev = document.getElementsByClassName("prev")[0], // 获取上一张的按钮
        next = document.getElementsByClassName("next")[0],//获取下一张的按钮
        span = document.getElementById("countBtn"), // 获取当前图片计数
        circulationNode = document.getElementsByClassName("circulation")[0],//获取循环按钮
        no_circulationNode = document.getElementsByClassName("no_circulation")[0],//获取非循环按钮
        index = 0,//建立一个索引
        bool = true; //加锁  初始化为可循环
    var imgArr = ["url(img/a1.jpg)", "url(img/a2.jpg)", "url(img/a3.jpg)", "url(img/a4.jpg)", "url(img/a5.jpg)"],//建立图片路径的数组
        len = imgArr.length - 1,
        temp1 = circulationNode.style,
        temp2 = no_circulationNode.style,
        imgBg = img.style; //优化效率

    //默认是循环所以先改变循环按钮的背景颜色
    temp1.background = 'yellowgreen';

    //定时器->每隔5秒钟自动更换一次图片
    var timer = setInterval(function () {
        //调用一次下一张的点击事件
        index++;
        bool ? (index = index > len ? 0 : index) : (index = index > len ? len : index);
        //三目运算
        imgBg.backgroundImage = `${imgArr[index]}`;//改编成对应图片的路径
        span.innerHTML = (index + 1) + "/" + (len + 1); //拿到当前图片的位置
    }, 5000);

    //上一张的按钮
    prev.onclick = function () {
        index--;
        bool ? (index = index < 0 ? len : index) : (index = index < 0 ? 0 : index);
        imgBg.backgroundImage = `${imgArr[index]}`; //改编成对应图片的路径
        span.innerHTML = (index + 1) + "/" + (len + 1); //拿到当前图片的位置
    }

    //下一张的按钮
    next.onclick = function () {
        index++;
        bool ? (index = index > len ? 0 : index) : (index = index > len ? len : index);
        imgBg.backgroundImage = `${imgArr[index]}`;//改编成对应图片的路径
        span.innerHTML = (index + 1) + "/" + (len + 1); //拿到当前图片的位置
    }

    //改变成循环模式的按钮
    circulationNode.onclick = function () {
        bool = true;
        temp1.background = 'yellowgreen';  //改变对应按钮的背景颜色
        temp2.background = '#2164f3';
    }

    //改变成非循环模式的按钮
    no_circulationNode.onclick = function () {
        bool = false;
        temp1.background = '#2164f3';
        temp2.background = 'yellowgreen';
    }
});

上述是平时你我经常练习的时候写的方法,下面我换一种方式,用构造函数来实现这个功能

值得注意点:

    function Slideshow(arr){
        this.bool = true;
        this.index = 0;
        this.len = arr.length - 1;
    }

首先构造一个构造函数,创建对应的变量保存在调用这个构造函数的对象内

var slideshow = new Slideshow(imgArr);

把路径的数组传入进去
上面的bool,index,len都被保存在了slideshow对象里面

在原型上写入方法求得不同情况下索引的值

    Slideshow.prototype = {
        prev : function(){
            this.index--;
            this.bool ? (this.index = this.index < 0 ? this.len : this.index) : (this.index = this.index < 0 ? 0 : this.index);
            return this.index;
        },
        next : function(){
            this.index++;
            this.bool ? (this.index = this.index > this.len ? 0 : this.index) : (this.index = this.index > this.len ? this.len : this.index);
            return this.index;
        }
    }

this指向的是调用这个方法的对象里面的属性
比如slideshow.prev();
那么在prev内部,this.index指的就是对象slideshow下的index属性

代码集合

(function () {
    var img = document.getElementsByClassName("contentImg")[0], //获取图片
        prevNode = document.getElementsByClassName("prev")[0], // 获取上一张的按钮
        nextNode = document.getElementsByClassName("next")[0],//获取下一张的按钮
        span = document.getElementById("countBtn"), // 获取当前图片计数
        circulationNode = document.getElementsByClassName("circulation")[0],//获取循环按钮
        no_circulationNode = document.getElementsByClassName("no_circulation")[0];//获取非循环按钮
    var imgArr = ["url(img/a1.jpg)", "url(img/a2.jpg)", "url(img/a3.jpg)", "url(img/a4.jpg)", "url(img/a5.jpg)"];//建立图片路径的数组

    function Slideshow(arr){
        this.bool = true;
        this.index = 0;
        this.len = arr.length - 1;
    }
    Slideshow.prototype = {
        prev : function(){
            this.index--;
            this.bool ? (this.index = this.index < 0 ? this.len : this.index) : (this.index = this.index < 0 ? 0 : this.index);
            return this.index;
        },
        next : function(){
            this.index++;
            this.bool ? (this.index = this.index > this.len ? 0 : this.index) : (this.index = this.index > this.len ? this.len : this.index);
            return this.index;
        }
    }
    var slideshow = new Slideshow(imgArr);

    var timer = setInterval(function(){
        var index = slideshow.next(); 
        img.style.backgroundImage = `${imgArr[index]}`;
        span.innerHTML = (index + 1) + "/" + (imgArr.length);
    },5000);

    prevNode.onclick = function(){
        var index = slideshow.prev(); 
        img.style.backgroundImage = `${imgArr[index]}`;
        span.innerHTML = (index + 1) + "/" + (imgArr.length);
    }
    nextNode.onclick = function(){
        var index = slideshow.next(); 
        img.style.backgroundImage = `${imgArr[index]}`;
        span.innerHTML = (index + 1) + "/" + (imgArr.length);
    }
    circulationNode.onclick = function(){
        slideshow.bool = true;
        this.style.background = 'yellowgreen';  //改变对应按钮的背景颜色
        no_circulationNode.style.background = '#2164f3';
    }
    no_circulationNode.onclick = function(){
        slideshow.bool = false;
        this.style.background = 'yellowgreen';  //改变对应按钮的背景颜色
        circulationNode.style.background = '#2164f3';
    }
});

原谅我讲的模糊,其实是懒哈哈哈,因为原型,构造函数起码还能再扯一个帖子,所以打算再后面的帖子看心情讲了

上面如有讲的不对的地方欢迎在下面留言讨论,好让博主我及时更正,一起学习,共同进步

源代码+素材:云盘地址提取码:pyl0
https://pan.baidu.com/s/1om0B-8ZP3N0H25yrAd4LQw
pyl0

你可能感兴趣的:(原生JavaScript实现图片切换)