ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

轮播的各种实现方式

2022-09-13 09:32:58  阅读:218  来源: 互联网

标签:function 轮播 方式 width 实现 wrapper li ul left


主要的业务逻辑

需求:

  1. 宽度自适应的走马灯,无限无缝轮播

    image

  2. 无限的头像展示走马灯

image

轮播图需要宽度自适应,头像的轮播的宽度是固定的

基于需求的 轮播/走马灯 各种实现方案:

  1. 正常的js实现

    实现:

    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta charset="UTF-8" />
    		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
    		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
    		<title>Document</title>
    		<style type="text/css">
    			* {
    				margin: 0px;
    				padding: 0px;
    				list-style: none;
    			}
    
    			#div1 {
    				width: 500px;
    				height: 125px;
    				margin: 60px auto 0px auto;
    				border: 2px solid lightgreen;
    				position: relative;
    				overflow: hidden;
    			}
    
    			#ul_img {
    				position: absolute;
    				top: 0;
    				left: 0;
    			}
    
    			#ul_img li {
    				float: left;
    				width: 125px;
    				height: 125px;
    				/*border: 1px solid red;*/
    			}
    
    			#ul_img li img {
    				width: 100%;
    				height: 100%;
    			}
    		</style>
    	</head>
    
    	<body>
    		<div id="div1">
    			<ul id="ul_img">
    				<li><img src="./upload/focus.jpg" alt="" /></li>
    				<li><img src="./upload/focus1.jpg" alt="" /></li>
    				<li><img src="./upload/focus2.jpg" alt="" /></li>
    				<li><img src="./upload/focus3.jpg" alt="" /></li>
    			</ul>
    		</div>
    		<script>
    			var millisec = 10; //滚动间隔时间(毫秒)
    			var intervalId;
    			var left = 0;
    			var ul;
    
    			window.onload = function () {
    				ul = document.getElementById('ul_img');
    				ul.innerHTML += ul.innerHTML; //复制一份相同的li
    				var lis = ul.getElementsByTagName('li');
    				// 重新设置宽度,但是计算的方法是基于第一张图片的宽度*元素的个数
    				ul.style.width = lis[0].offsetWidth * lis.length + 'px';
    				intervalId = setInterval('scroll()', millisec);
    
    				var div1 = document.getElementById('div1');
    
    				div1.onmouseover = function () {
    					clearInterval(intervalId);
    				};
    
    				div1.onmouseout = function () {
    					intervalId = setInterval('scroll()', millisec);
    				};
    			};
    
    			function scroll() {
    				left -= 1;
    				//定位小于等于总宽度的二分之一时,则left设置为0
    				if (left <= -ul.offsetWidth / 2) left = 0;
    				ul.style.left = left + 'px';
    			}
    		</script>
    	</body>
    </html>
    
    

    问题:只能在图片定宽的情况下实现

image

  1. 改版的js实现

    方式:基于方式一的原理,获取所有图片的偏移量,动态计算ul的宽度

    	<script>
    		window.onload = function () {
    			let intervalTime = 5;
    			let liMargin = 30;
    			let liWidth = []; // 提前初始化用来装所有li的offsetWidth
    			let left = 0; // 初始化left的值
    
    			let ul = document.getElementById('swiper_box').getElementsByTagName('ul')[0];
    			let li = ul.getElementsByTagName('li');
    
    			ul.innerHTML = ul.innerHTML + ul.innerHTML; // 将内容复制首中尾两分
    			li = [...ul.children]; // html类数组 转化 为数组
    
    			li.forEach(item => {
    				// 获取所有li的宽度,并且加上右边框的宽度
    				liWidth.push(item.clientWidth + liMargin);
    			});
    
    			let ulWidth = liWidth.reduce((tmp, item) => tmp + item); // 将所有的li的宽度累加
    			ul.style.width = ulWidth + liMargin + 'px'; // 根据计算出来的重新设置ul的高度,再加上收尾两边的边距
    
    			// 开启定时器调用调用滚动函数
    			let intervalID = setInterval(turnOnScroll, intervalTime);
    
    			ul.onmouseover = function () {
    				clearInterval(intervalID);
    			};
    
    			ul.onmouseout = function () {
    				intervalID = setInterval(turnOnScroll, intervalTime);
    			};
    			console.log(ul.children.length);
    			function turnOnScroll(params) {
    				left = left - 1;
    				if (left <= -ul.clientWidth / 2) left = `-${ul.children.length}`;
    				ul.style.left = left + 'px';
    			}
    		};
    	</script>
    

    问题:有一点点偏移量的误差,实际效果会有一点卡顿的感觉

  2. css3动画的实现

    实现:基于动画的关键帧,控制定位的具体位置

    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta charset="UTF-8" />
    		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
    		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
    		<title>Document</title>
    		<style>
    			/* 视口大小 */
    			.wrapper {
    				position: relative;
    				height: 100px;
    				width: 300px;
    				overflow: hidden;
    			}
    
    			/* 实际的内容盒子 */
    			.wrapper__box-wrapper {
    				height: 100px;
    				width: 900px;
    				position: absolute;
    				left: 0px;
    				background: #409eff;
    				animation: move 5s linear infinite;
    			}
    
    			/* 上下行的容器 */
    			.wrapper__box-wrapper__line {
    				/* 解决浮动导致的边距塌陷的问题 */
    				overflow: hidden;
    				margin: 10px 0;
    			}
    
    			/* 上下行容器内的两份内容 */
    			/* 文字盒子的自适应: width: 50% + flex均分 */
    			.wrapper__box-wrapper__line div {
    				float: left;
    				display: flex;
    				width: 50%;
    			}
    
    			.wrapper__box-wrapper__line span {
    				text-align: center;
    				background: rgba(255, 255, 255, 0.5);
    				color: #fff;
    				padding: 0 5px;
    				margin-right: 10px;
    				border-radius: 5px;
    				flex: 1 0 auto;
    				line-height: 35px;
    			}
    			@keyframes move {
    				0% {
    					left: 0;
    				}
    				100% {
    					left: -450px;
    				}
    			}
    		</style>
    	</head>
    	<body>
    		<div class="wrapper">
    			<div class="wrapper__box-wrapper">
    				<div class="wrapper__box-wrapper__line">
    					<div>
    						<span>什么是快乐星球</span>
    						<span>爷青回</span>
    						<span>躺平</span>
    						<span>惊呆了</span>
    					</div>
    					<div>
    						<span>什么是快乐星球</span>
    						<span>爷青回</span>
    						<span>躺平</span>
    						<span>惊呆了</span>
    					</div>
    				</div>
    				<div class="wrapper__box-wrapper__line">
    					<div>
    						<span>requestAnimationFrame</span>
    						<span>setTimeout</span>
    						<span>setInterval</span>
    					</div>
    					<div>
    						<span>requestAnimationFrame</span>
    						<span>setTimeout</span>
    						<span>setInterval</span>
    					</div>
    				</div>
    			</div>
    		</div>
    	</body>
    </html>
    
    

    问题:也是需要定宽,或者是知道图片列表的总宽度,才能基于关键帧进行定位

  3. swiper组件的实现

    很多细节无法自定义

    因为宽度自适应,所以无法实现匀速的线性滚动

    并且无法实现hover的放大效果

    拖动后不能继续播放

    .swiper-wrapper {
    	height: 400px;
    	width: 100vw;
    	/* 改变swiper动画的实现曲线 */
    	-webkit-transition-timing-function: linear; /*之前是ease-out*/
    	-moz-transition-timing-function: linear;
    	-ms-transition-timing-function: linear;
    	-o-transition-timing-function: linear;
    	transition-timing-function: linear;
    	margin: 0 auto;
    }
    .swiper-wrapper .swiper-slide {
    	height: 400px;
    	width: auto;
    }
    .swiper-wrapper img {
    	max-width: 100%;
    	max-height: 100%;
    	display: block;
    	margin: auto;
    	border-radius: 16px;
    	height: 400px;
    	object-fit: cover;
    }
    
    
    <script>
      var swiper = new Swiper('.mySwiper', {
        loop: true,
        speed: 2500, // 缓动时长
        //用户操作swiper之后,是否禁止autoplay.默认为true:停止。
        // autoplayDisableOnInteraction: false,
        // grabCursor: true, // 显示拖动小手
        // centeredSlides: true, // 设定为true时,当前的active slide 会居中,而不是默认状态下的居左。
        // slidesOffsetBefore: 100, // 起始偏移量
        spaceBetween: 20,
        slidesPerView: 'auto',
        freeMode: true,
        autoplay: {
          delay: 0,
          disableOnInteraction: false, //就算触摸了也继续滚动
          stopOnLastSlide: false,
        },
      });
    </script>
    

补充:基于表格的实现形式:https://www.cnblogs.com/JiangXiaoTian/articles/2550540.html

标签:function,轮播,方式,width,实现,wrapper,li,ul,left
来源: https://www.cnblogs.com/ecat-octopus/p/16688086.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有