原生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脚本语言在网页中的简单应用
May 13 Javascript
javascript 有用的脚本函数
May 07 Javascript
JS模拟的QQ面板上的多级可展开的菜单
Oct 10 Javascript
jquery通过a标签删除table中的一行的代码
Dec 02 Javascript
用Angular实时获取本地Localstorage数据,实现一个模拟后台数据登入的效果
Nov 09 Javascript
值得分享的JavaScript实现图片轮播组件
Nov 21 Javascript
js实现文字选中分享功能
Jan 25 Javascript
React如何将组件渲染到指定DOM节点详解
Sep 08 Javascript
element ui table(表格)实现点击一行展开功能
Dec 04 Javascript
gulp构建小程序的方法步骤
May 31 Javascript
js使用cookie实现记住用户名功能示例
Jun 13 Javascript
VUE实现图片验证码功能
Nov 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 STRING 陷阱原理说明
2010/07/24 PHP
迪菲-赫尔曼密钥交换(Diffie?Hellman)算法原理和PHP实现版
2015/05/12 PHP
在Z-Blog中运行代码[html][/html](纯JS版)
2007/03/25 Javascript
Firefox getBoxObjectFor getBoundingClientRect联系
2008/10/26 Javascript
javascript URL编码和解码使用说明
2010/04/12 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
2013/01/23 Javascript
Fullpage.js固定导航栏-实现定位导航栏
2016/03/17 Javascript
js获取当前时间(昨天、今天、明天)
2016/11/23 Javascript
HTML5 js实现拖拉上传文件功能
2020/11/20 Javascript
详解Angular5 服务端渲染实战
2018/01/04 Javascript
element UI upload组件上传附件格式限制方法
2018/09/04 Javascript
vue强制刷新组件的方法示例
2019/02/28 Javascript
vue中实现点击按钮滚动到页面对应位置的方法(使用c3平滑属性实现)
2019/12/29 Javascript
基于vue.js仿淘宝收货地址并设置默认地址的案例分析
2020/08/20 Javascript
vue中watch的用法汇总
2020/12/28 Vue.js
python文件和目录操作函数小结
2014/07/11 Python
Python中数组,列表:冒号的灵活用法介绍(np数组,列表倒序)
2018/04/18 Python
pandas groupby 分组取每组的前几行记录方法
2018/04/20 Python
Django项目实战之用户头像上传与访问的示例
2018/04/21 Python
学生信息管理系统Python面向对象版
2019/01/30 Python
使用Python检测文章抄袭及去重算法原理解析
2019/06/14 Python
在python3中实现更新界面
2020/02/21 Python
查看keras的默认backend实现方式
2020/06/19 Python
浅谈Python xlwings 读取Excel文件的正确姿势
2021/02/26 Python
CSS3 边框效果
2019/11/04 HTML / CSS
html5理解head_动力节点Java学院整理
2017/07/13 HTML / CSS
世界著名的顶级牛排:Omaha Steak(奥马哈牛排)
2016/09/20 全球购物
意大利体育用品和运动服网上商店:Maxi Sport
2019/09/14 全球购物
Hobbs官方网站:英国奢华女性时尚服装
2020/02/22 全球购物
大学生学业生涯规划
2014/01/05 职场文书
学校安全检查制度
2014/01/27 职场文书
关于读书的演讲稿
2014/05/07 职场文书
优秀语文教师事迹
2014/05/18 职场文书
马丁路德金演讲稿
2014/05/19 职场文书
2015年征兵工作总结
2015/07/23 职场文书
计算机教师工作总结
2015/08/13 职场文书