原生js实现3D轮播图


Posted in Javascript onMarch 21, 2020

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样式时,要注意格式

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

Javascript 相关文章推荐
javascript学习笔记(十三) js闭包介绍(转)
Jun 20 Javascript
Javascript实现滑块滑动改变值的实现代码
Apr 12 Javascript
javascript中怎么做对象的类型判断
Nov 11 Javascript
JQuery中阻止事件冒泡几种方式及其区别介绍
Jan 15 Javascript
Node.js项目中调用JavaScript的EJS模板库的方法
Mar 11 Javascript
jQuery获取同级元素的简单代码
Jul 09 Javascript
JSON与JS对象的区别与对比
Mar 01 Javascript
React组件之间的通信的实例代码
Jun 27 Javascript
深入理解JavaScript的async/await
Aug 05 Javascript
详解vue移动端项目的适配(以mint-ui为例)
Aug 17 Javascript
JavaScript中的垃圾回收与内存泄漏示例详解
May 02 Javascript
如何利用React实现图片识别App
Feb 18 Javascript
解决layui弹出层layer的area过大被遮挡的问题
Sep 21 #Javascript
关于layui flow loading占位图的实现方法
Sep 21 #Javascript
layui switch 开关监听 弹出确定状态转换的例子
Sep 21 #Javascript
微信小程序实现3D轮播图效果(非swiper组件)
Sep 21 #Javascript
微信小程序自定义波浪组件使用方法详解
Sep 21 #Javascript
LayUi使用switch开关,动态的去控制它是否被启用的方法
Sep 21 #Javascript
LayUI switch 开关监听 获取属性值、更改状态的方法
Sep 21 #Javascript
You might like
php array_unique之后json_encode需要注意
2011/01/02 PHP
ThinkPHP做文字水印时提示call an undefined function exif_imagetype()解决方法
2014/10/30 PHP
php中mkdir函数用法实例分析
2014/11/15 PHP
javascript replace方法与正则表达式
2008/02/19 Javascript
表单JS弹出填写提示效果代码
2011/04/16 Javascript
圣诞节Merry Christmas给博客添加浪漫的下雪效果基于jquery实现
2012/12/27 Javascript
javascript闭包的高级使用方法实例
2013/07/04 Javascript
把文本中的URL地址转换为可点击链接的JavaScript、PHP自定义函数
2014/07/29 Javascript
Node.js中使用Log.io在浏览器中实时监控日志(等同tail -f命令)
2014/09/17 Javascript
简单谈谈jQuery(function(){})与(function(){})(jQuery)
2014/12/19 Javascript
JS动态日期时间的获取方法
2015/09/28 Javascript
原生JavaScript实现异步多文件上传
2015/12/02 Javascript
Node.js的项目构建工具Grunt的安装与配置教程
2016/05/12 Javascript
JavaScript中数组slice和splice的对比小结
2016/09/22 Javascript
EasyUI折叠表格层次显示detailview详解及实例
2016/12/28 Javascript
Javascript中 带名 匿名 箭头函数的重要区别(推荐)
2017/01/29 Javascript
Angular2使用Angular-CLI快速搭建工程(二)
2017/05/21 Javascript
解决vue-cli中stylus无法使用的问题方法
2017/06/19 Javascript
VueJs单页应用实现微信网页授权及微信分享功能示例
2017/07/26 Javascript
vue项目实现记住密码到cookie功能示例(附源码)
2018/01/31 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
JavaScript实现多文件下载方法解析
2020/08/07 Javascript
Python使用Socket(Https)Post登录百度的实现代码
2012/05/18 Python
Python实现向服务器请求压缩数据及解压缩数据的方法示例
2017/06/09 Python
python3 pillow生成简单验证码图片的示例
2017/09/19 Python
Django自定义用户认证示例详解
2018/03/14 Python
python2.7实现FTP文件下载功能
2018/04/15 Python
使用python3调用wxpy模块监控linux日志并定时发送消息给群组或好友
2019/06/05 Python
CSS3网格的三个新特性详解
2014/04/04 HTML / CSS
经贸专业毕业生求职信范文
2014/05/01 职场文书
上课睡觉万能检讨书
2015/02/17 职场文书
2015年教师节慰问信
2015/03/23 职场文书
初中英语教师个人工作总结2015
2015/07/21 职场文书
解决goland 导入项目后import里的包报红问题
2021/05/06 Golang
MySQL约束超详解
2021/09/04 MySQL
多台电脑共享文件怎么设置?多台电脑共享文件操作教程
2022/04/08 数码科技