原生js实现3D轮播图

3D轮播图是我做过复杂的图片轮播了,由于是利用坐标,层级之间的关系,所以实现起来原理比较简单但是bug巨多,在推推拖拖了好久后,下定决心重新整理成博客,与大家分享!

首先分析一下3D图片轮播的功能需求:

和其它图片轮播大体一致,无非就是点击按钮向左、右翻页,点击下方提示位置小点切换到小点表示对的位置页(我是真的不知道那个小点叫什么名字,大家将就着听吧)

上代码:

基本代码:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>立体轮播图</title>
 <style>
 .block{
  position: relative;
  width: 900px;
  height: 370px;
  margin: 0 auto;
  overflow: hidden;
 }
 .imgae_div{
  position: relative;
  width: 900px;
  height: 300px;
 }
 .imgae_div>div{
  position: absolute;
  width: 400px;
  height: 200px;
  transition: all 1s linear;

 }
 .imgae_div img{
  width: 400px;
  height: 200px;
 }
 .imgae_div>div:nth-child(1){
  top: 150px;
  left: 250px;
  z-index: 6;
 }
 .imgae_div>div:nth-child(2){
  top: 100px;
  left: 0px;
  z-index: 5;
 }
 .imgae_div>div:nth-child(3){
  top: 50px;
  left: 0px;
  z-index: 4;
 }
 .imgae_div>div:nth-child(4){
  top: 0px;
  left: 250px;
  z-index: 3;
 }
 .imgae_div>div:nth-child(5){
  top: 50px;
  left: 500px;
  z-index: 4;
 }
 .imgae_div>div:nth-child(6){
  top: 100px;
  left: 500px;
  z-index: 5;
 }
 .btn{
  width: 900px;
  height: 40px;
  position: absolute;
  top: 155px;
  z-index: 999;
  overflow: hidden;
 }
 .btn>span:nth-child(1){
  width: 30px;
  background-color: rgba(164, 150, 243, 0.336);
  display: block;
  float: left;
  text-align: center;
  line-height: 40px;
  margin-left: -30px;
  cursor: pointer;
  opacity: 0;
  transition: all 0.5s linear;
 }
 .btn>span:nth-child(2){
  width: 30px;
  background-color: rgba(164, 150, 243, 0.336);
  display: block;
  float: right;
  text-align: center;
  line-height: 40px;
  margin-right: -30px;
  cursor: pointer;
  opacity: 0;
  transition: all 0.5s linear;
 }
 .marright{
  margin-right: 0px !important;
  opacity: 1 !important;
 }
 .marleft{
  margin-left: 0px !important;
  opacity: 1 !important;
 }
 .point{
  width: 108px;
  height: 14px;
  position: absolute;
  bottom: 0;
  left: 396px;
  z-index: 10;

 }
 .point>div{
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background-color: white;
  float: left;
  margin: 0 2px;
  border: 2px solid black;
  box-sizing: border-box;
 }
 </style>
</head>
<body>
 <div class="block">
 <div class="imgae_div">
  <div><img src="./img/111.jpg" alt=""></div>
  <div><img src="./img/222.jpg" alt=""></div>
  <div><img src="./img/333.jpg" alt=""></div>
  <div><img src="./img/444.jpg" alt=""></div>
  <div><img src="./img/555.jpg" alt=""></div>
  <div><img src="./img/666.jpg" alt=""></div>
 </div>
 <div class="btn">
  <span><</span>
  <span>></span>
 </div>
 <div class="point">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
 </div>
 </div>
 <script src="./js/index.js"></script>
</body>
</html>

js代码:

// 简单说一下我是怎么想的:1.分步实现,先实现图片自己动,在加其它的功能
// 2.每实现一个功能要立马去测bug,因为放到后面就越难找了。
// 3.轮播向左,向右是两个互相联系的方法,需要找到彼此的关系
var imgae_div = document.getElementsByClassName('imgae_div')[0];
var imgae_div_child = imgae_div.children;
var btn=document.getElementsByClassName('btn')[0];
var block=document.getElementsByClassName('block')[0];
var new_point = document.getElementsByClassName("point")[0].children;
new_point[0].style.backgroundColor = "#000000";
// 利用函数的封装 ps:图片轮播离不开计时器,且个人觉得用setIntervar比较多
img_work();
function img_work() {
 time = setInterval(function () {
 img_workfirst('left', 0);//两个参数,判断向左还是向右轮播,索引
 }, 1500);
}
// console.log(point.child);
function img_workfirst(left_right, cindex) {
 // 这里面首先说一下css中写好的默认层关系:从第1张到第6张为别为 6 5 4 3 4 5,和页面的布局有关
 var firstpage = {//当前页的各种属性
 // getComputedStyle()获取css属性
 left: window.getComputedStyle(imgae_div_child[cindex]).left,
 top: window.getComputedStyle(imgae_div_child[cindex]).top,
 zIndex: window.getComputedStyle(imgae_div_child[cindex]).zIndex,
 backcolor: window.getComputedStyle(new_point[cindex]).backgroundColor
 };
 if (left_right == 'left') {
 // 向左轮播为默认轮播
 for (var i = 0; i < imgae_div_child.length; i++) {
  // for循环遍历所有元素
  if (i == imgae_div_child.length - 1) {
  // 当前页的下一张为 最后一张(位置都是动态切换的)
  imgae_div_child[i].style.left = firstpage.left;
  imgae_div_child[i].style.top = firstpage.top;
  imgae_div_child[i].style.zIndex = firstpage.zIndex;
  new_point[i].style.backgroundColor = firstpage.backcolor;
  }
  else {
  // 其它页对应为它前面元素的属性
  imgae_div_child[i].style.left = window.getComputedStyle(imgae_div_child[i + 1]).left;
  imgae_div_child[i].style.top = window.getComputedStyle(imgae_div_child[i + 1]).top;
  imgae_div_child[i].style.zIndex = window.getComputedStyle(imgae_div_child[i + 1]).zIndex;
  new_point[i].style.backgroundColor = window.getComputedStyle(new_point[i + 1]).backgroundColor;

  }
 }
 }
 // 向右轮播,借助向左轮播分析
 else {
 for (var i = imgae_div_child.length - 1; i >= 0; i--) {
  if (i == 0) {
  imgae_div_child[i].style.left = firstpage.left;
  imgae_div_child[i].style.top = firstpage.top;
  imgae_div_child[i].style.zIndex = firstpage.zIndex;
  new_point[i].style.backgroundColor = firstpage.backcolor;

  }
  else {
  imgae_div_child[i].style.left = window.getComputedStyle(imgae_div_child[i - 1]).left;
  imgae_div_child[i].style.top = window.getComputedStyle(imgae_div_child[i - 1]).top;
  imgae_div_child[i].style.zIndex = window.getComputedStyle(imgae_div_child[i - 1]).zIndex;
  new_point[i].style.backgroundColor = window.getComputedStyle(new_point[i - 1]).backgroundColor;

  }
 }
 }
 firstpage = null;
 // 将表示当前页的数据清空,防止bug(因为当前页也是动态变化的,需要动态创建)
}
// console.log(new_point);

// 消除一些bug
window.onblur = function () {//窗口失焦时,计时器停止
 clearInterval(time);
}
window.onfocus = function () {
 img_work();//获焦时开启计时器
}
document.onselectstart = function () {//禁止用户复制
 return false;
}
block.οnmοuseenter=function(){//鼠标进入轮播图时,两个按钮滑动出来
 clearInterval(time);
 btn.children[1].className='marright';
 btn.children[0].className='marleft';
}
block.οnmοuseleave=function(){//离开时和平时隐藏
 img_work();
 btn.children[1].className='';
 btn.children[0].className='';
 for (var k = 0; k < imgae_div_child.length; k++) {
 imgae_div_child[k].style.transitionDuration = "0.5s";
 }
}
// 对应的左右按钮的点击事件
btn.children[0].οnclick=function(event){
 if(event.detail==1){//用于控制鼠标的连击,但是效果对于故意测试来说还是有所缺陷 下同
 img_workfirst('left',0);
 }
}
btn.children[1].οnclick=function(event){
 if(event.detail==1){
 img_workfirst('right',imgae_div_child.length-1);
 }
}

// point的事件
for(var i=0;i<new_point.length;i++){
 new_point[i].index=i;
 new_point[i].οnclick=function(){
 for(var k=0;k<imgae_div_child.length;k++){
  imgae_div_child[k].style.transitionDuration='0.1s';//动画完成
 }
 var oldindex=0;
 for(var k=0;k<new_point.length;k++){
  if(new_point[k].style.backgroundColor== 'rgb(0, 0, 0)'){//格式必须统一
  oldindex=new_point[k].index;
  }
 }
 var num =0;//判断计算转动次数
 if(this.index>oldindex){//所需页在当前页的左(左右相对于下方点来说)
  num=this.index-oldindex;
  var timego=setInterval(function(){
  num--;
  if(num<0){
   clearInterval(timego);
  }
  else{
   img_workfirst('right',5)//因为方向变了,所以下一页就为当前页的上一页,也就是cindex为5
  }
  },100);//动画时间缩短,优化体验
 }
 else{//所需页在当前页的左(左右相对于下方点来说)
  num=Math.abs(this.index-oldindex);
  var timego=setInterval(function(){
  num--;
  if(num<0){
   clearInterval(timego);
  }
  else{
   img_workfirst('left',0)
  }
  },100);
 }
}
}

关于出现的bug的一些总结:

1、注意左右的区分与联系
2、注意连续点击的bug
3、注意切换窗口,切换页面,最小化等这些切换的bug
4、注意代码格式,在js中写css样式时,要注意格式

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js实现轮播图的完整代码

    今天写一个完整的轮播图,首先它需要实现三个功能: 1.鼠标放在小圆点上实现轮播 2.点击焦点按钮实现轮播 3.无缝自动轮播 轮播图的原理: 一系列的大小相等的图片平铺,利用CSS布局只显示一张图片,其余隐藏.通过计算偏移量(封装一个动画函数)自动播放,或通过手动点击事件切换图片. html布局: <div id="box" class="all"> <div class="inner"> <!-- 相框-->

  • 原生js实现轮播图的示例代码

    很多网站上都有轮播图,但却很难找到一个系统讲解的,因此这里做一个简单的介绍,希望大家都能有所收获,如果有哪些不正确的地方,希望大家可以指出. 原理: 将一些图片在一行中平铺,然后计算偏移量再利用定时器实现定时轮播. 步骤一:建立html基本布局 如下所示: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>轮播图</title> </hea

  • js实现支持手机滑动切换的轮播图片效果实例

    本文实例讲述了js实现支持手机滑动切换的轮播图片效果的方法.分享给大家供大家参考.具体如下: 运行效果如下: 完整实例代码点击此处本站下载. 使用方法案例: <script type="text/javascript" src="../src/zepto.js"></script> <script type="text/javascript" src="../src/carousel-image.js&qu

  • 原生js实现无限循环轮播图效果

    知识要点 1.实现无限循环的原理: 以偏移的距离来判断是否跳回第一张和最后一张 也可以利用循环判断图片的当前索引值 var newLeft=parseInt(list.style.left)+offset;//当前的偏移量+下一次的偏移量=新的偏移量 list.style.left=newLeft+"px";//当前的偏移值=新的偏移值 //以偏移的距离来判断是否跳回第一张和最后一张 if(newLeft>-600){ list.style.left=-3000+"px

  • JS实现左右无缝轮播图代码

    废话不多说了,直接给大家贴代码了. 无缝轮播图: <title>无缝轮播图</title> <style> *{margin: 0;padding:0; } ul{list-style: none;} .banner{width: 600px;height: 300px;border: 2px solid #ccc;margin: 100px auto;position: relative;overflow: hidden;} .img{position: absolu

  • JS实现自动轮播图效果(自适应屏幕宽度+手机触屏滑动)

    1.本文使用js+jQuery实现轮播图,需要引用jquery包,另种实现分别是animate实现自适应的轮播,以及transform平滑轮播(在注释代码中). 2.代码中的图片大家自己更换就可以了,样式和逻辑均写在js里. 3.html标签代码,js代码 <div class="slider"> //轮播箭头 <p class="lastpic"><img src="../images/prev.png">&

  • js实现点击左右按钮轮播图片效果实例

    本文实例讲述了js实现点击左右按钮轮播图片效果的方法.分享给大家供大家参考.具体实现方法如下: $(function () { var index = 1; var pPage = 1; var $v_citemss = $(".citemss"); var $v_show = $v_citemss.find("ul"); v_width = $v_citemss.width();//图片展示区外围div的大小 //注:若为整数,前边不能再加var,否则会被提示un

  • zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题

    在移动web开发中,由于手机界面较小,为了能展示更多的图片经常使用轮播图并且还需要考虑到手机流量的问题,通过请教他人以及百度,个人感觉swipe.js比较好用. 它是一个纯javascript工具,不需要跟其它js库一起导入,同时兼容jQuery和zepto,压缩版的大小只有6kb很适合移动端的开发,它的git地址:https://github.com/thebird/swipe 在git上对其的使用方式介绍的相当清楚,关键代码如下 <div id='slider' class='swipe'>

  • 基于vue.js轮播组件vue-awesome-swiper实现轮播图

    一般做移动端轮播图的时候,最常用的就是Swiper插件了,而vue.js也有一个轮播组件vue-awesome-swiper,用法跟swiper相似. 1.安装vie-awesome-swiper nam install vue-awesome-swiper --save-dev 2.引用vie-awesome-swiper组件,这里我是用vie-cli创建的项目,在main.js: import VueAwesomeSwiper from 'vue-awesome-swiper'; Vue.u

  • JS轮播图实现简单代码

    本文实例为大家分享了js轮播图实现代码,供大家参考,具体内容如下 思路: 1.首先要有个盛放图片的容器,设置为单幅图片的宽高,且overflow:hidden,这样保证每次可以只显示一个图片 2.Container内有个放图片的list进行position的定位 ,其中的图片采用float的方式,同时当图片进行轮播时,改变list的Left值使得其显示的图片发生变化. 3.图片的轮播使用定时器,通过定时器改变list的Left值是的图片循环展示 4.当鼠标滑动到图片上时,清除定时器,图片停止轮播

随机推荐