原生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 相关文章推荐
document.all与WEB标准
May 13 Javascript
JavaScript实用技巧(一)
Aug 16 Javascript
js切换光标示例代码
Oct 10 Javascript
javascript验证内容为数字以及长度为10的简单实例
Aug 20 Javascript
JS取数字小数点后两位或n位的简单方法
Oct 24 Javascript
jQuery插件HighCharts绘制2D圆环图效果示例【附demo源码下载】
Mar 09 Javascript
详解node服务器中打开html文件的两种方法
Sep 18 Javascript
VUE饿了么树形控件添加增删改功能的示例代码
Oct 17 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
Jul 20 Javascript
vue实现循环切换动画
Oct 17 Javascript
layer.prompt输入层的例子
Sep 24 Javascript
Vue实现数据请求拦截
Oct 23 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
smarty实例教程
2006/11/19 PHP
thinkPHP通用控制器实现方法示例
2017/11/23 PHP
TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例
2018/09/03 PHP
用js计算页面执行时间的函数
2006/12/07 Javascript
js 多种变量定义(对象直接量,数组直接量和函数直接量)
2010/05/24 Javascript
打造个性化的功能强大的Jquery虚拟键盘(VirtualKeyboard)
2014/10/11 Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
2015/02/13 Javascript
Javascript中For In语句用法实例
2015/05/14 Javascript
jQuery如何解决IE输入框不能输入的问题
2016/10/08 Javascript
JavaScript正则获取地址栏中参数的方法
2017/03/02 Javascript
JavaScript该如何学习 怎样轻松学习JavaScript
2017/06/12 Javascript
jQuery之动画ajax事件(实例讲解)
2017/07/18 jQuery
JavaScript与Java正则表达式写法的区别介绍
2017/08/15 Javascript
javascript 面向对象实战思想分享
2017/09/07 Javascript
在vue中把含有html标签转为html渲染页面的实例
2019/10/28 Javascript
js+canvas实现刮刮奖功能
2020/09/13 Javascript
如何在 Vue 表单中处理图片
2021/01/26 Vue.js
Python实现比较两个文件夹中代码变化的方法
2015/07/10 Python
解决pyqt中ui编译成窗体.py中文乱码的问题
2016/12/23 Python
利用Python半自动化生成Nessus报告的方法
2019/03/19 Python
python使用beautifulsoup4爬取酷狗音乐代码实例
2019/12/04 Python
关于pytorch中全连接神经网络搭建两种模式详解
2020/01/14 Python
详解python内置模块urllib
2020/09/09 Python
原生canvas制作画图小工具的踩坑和爬坑
2020/06/09 HTML / CSS
阿迪达斯加拿大官网:Adidas加拿大
2016/08/25 全球购物
俄罗斯达美乐比萨外送服务:Domino’s Pizza
2020/12/18 全球购物
Java中实现多态的机制是什么?
2014/12/07 面试题
abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?
2012/10/15 面试题
一名女生的自荐信
2013/12/08 职场文书
咖啡馆创业计划书
2014/01/26 职场文书
2014年体育教学工作总结
2014/12/09 职场文书
巴黎圣母院观后感
2015/06/10 职场文书
毕业典礼主持词
2015/06/29 职场文书
情况说明书格式及范文
2019/06/24 职场文书
POST提交数据常见的四种方式
2022/01/18 HTML / CSS
MySQL数据库查询进阶之多表查询详解
2022/04/08 MySQL