H5移动端,如何写一套自己的组件库,适配方法,less适配

uniapp开发app、h5和微信小程序,8大好用的组件库推荐 是一个基于 Vue3 的跨平台组件库,支持 uni-app 的 H5、App、小程序等平台。是目前最流行的 uni-app 前端 UI 框架之一,具有丰富的组件和工具方法。根据项目的具体需求和团队的技术栈,选择适合的组件库能够显著提升开发效率和用户体验。是一个优秀的视觉风格组件库,主打强大的视觉效果和丰富的 UI 设计。是京东开源的移动端 Vue2/3 组件库,支持 uni-app。是有赞开源的小程序组件库,可以通过适配 uni-app 使用。适用的组件库,以及它们的特点和推荐场景。 阅读详情

一、无缝滑屏轮播组件(使用定位)

1、不是无缝的滑屏轮播

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0" /> -->
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<meta name="format-detection" content="telephone=no,email=no"/>
		<title></title>
		<style type="text/css">
			*{margin: 0;padding: 0;}
			html,body{height: 100%;overflow: hidden;}
			#wrap{height: 100%;overflow: hidden;}
			#wrap .carouse_wrap > .list{list-style: none;overflow: hidden;position: absolute;}
			#wrap .carouse_wrap > .list > li{float: left;}
			#wrap .carouse_wrap > .list > li > a,#wrap .carouse_wrap > .list > li > a > img{display: block;}
			#wrap .carouse_wrap > .list > li > a > img{width: 100%;}
		</style>
	</head>
	<body>
		<div id="wrap"><!-- 用来布局的,包裹轮播图,设置轮播图在页面位置 -->
			<div class="carouse_wrap"><!-- 轮播容器 -->
			</div>
		</div>
	</body>
	<script type="text/javascript">			
		window.onload=function(){
			/* 全局禁用默认事件触发 */
			document.addEventListener("touchstart",function(ev){
				ev=event||ev;
				ev.preventDefault();
			});
			
			/* 动态生成轮播图 */
			let arr = ["img/01.jpg","img/02.jpg","img/03.jpg","img/04.jpg","img/05.jpg"];//模拟从后台获取的轮播图列表
			
			let carouse_wrap = document.querySelector(".carouse_wrap");//获取轮播容器
			
			if(carouse_wrap){//如果轮播存在
				/* dom结点 */
				let ul = document.createElement("ul");		//创建一个ul结点
				let style = document.createElement("style");//创建一个style结点
				let head = document.querySelector("head");	//获取head结点
				
				ul.classList.add("list")					//给创建的ul的class列表添加一个.list样式
				
				for(let i = 0;i<arr.length;i++){//遍历数组,有多少图片就添加多少轮播结构
					ul.innerHTML+='<li><a href="javascript:;"><img src="'+arr[i]+'" ></a></li>'
				}
				
				carouse_wrap.appendChild(ul)				//把ul添加到容器中
				
				/* (重点)给style结点添加样式,首先
					我们应该先确定单张图片的大小,这里我就直接用百分比让图片填满屏幕了
					那么,我们应该让ul的宽度正好容纳这些轮播图片,比如5张图片就是500%
					
					那么5张图片,每张就占ul的20%,5*20%=100%,正好填满ul
				 */
				style.innerHTML="#wrap .carouse_wrap > .list{width: "+arr.length*100+"%;}#wrap .carouse_wrap > .list > li{width: "+100/arr.length+"%;}"
				
				head.appendChild(style)//将style结点添加到head中
				
				/* 最后,因为每个li都设置的定位,容器就没有东西撑开造成高度塌陷,我们只需要让其等于图片高度即可 */
				let img = document.querySelector("#wrap .carouse_wrap > .list > li:nth-of-type(1) > a > img");
				
				let timer=setTimeout(function(){/* 因为js代码执行很快,页面没渲染好就获取offsetHeight会获取不到,等100ms就可以了 */
					carouse_wrap.style.height=img.offsetHeight+"px"
				},100)
				clearTimeout(timer)//清除
				
				/* ==================创建轮播完================= */
				/* ==================滑屏======================= */
				let ElStartX = 0;	//元素当前位置
				let startX = 0;		//记录手点击起始位置
				let moveX = 0;		//记录手指滑动距离
				let endX = 0;		//记录手指抬起时位置
				let index = 0;		//记录当前轮播的下标
				/* 手指点击屏幕事件 获取手指和当前元素位置*/
				carouse_wrap.addEventListener("touchstart",function(ev){
					ev = event||ev;
					startX = ev.changedTouches[0].clientX;//获取手指点击位置
					
					ElStartX = ul.offsetLeft;//获取元素当前位置
					
				})
				/* 手指移动事件 让元素跟随手指移动*/
				carouse_wrap.addEventListener("touchmove",function(ev){
					ev = ev||event;
					ul.style.transition="none";					//清除过渡,在手指抬起事件中绑定,这里要清掉,因为影响滑屏体验
					let nowX = ev.changedTouches[0].clientX;	//获取滑动时的位置
					moveX = nowX - startX;						//获取滑动距离
					ul.style.left = ElStartX + moveX + "px";	//让ul跟随手指偏移
				})
				/* 手指抬起事件 判断移动距离,如果超过100px的距离,就让轮播跳转到下一张或上一张,第一张和最后一张怎么滑都会回到原来的位置*/
				carouse_wrap.addEventListener("touchend",function(ev){
					ev = ev||event;
					if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
						index===0?index=0:index--;		//如果index=0了就让index=4,否则就自减
					}else if(moveX < 0 && moveX <= -100){
						index===4?index=4:index++;
					}
					ul.style.transition="1s left";//设置动画,在手指抬起时才设置
					
					ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
					
					/* 方式2
						let index = ul.offsetLeft/img.offsetWidth;//获取实时的位置,用ul的当前偏移/轮播宽度,就会得到一个数
						这个数如果你向右滑屏会得到一个正数,如果你刚好滑满一屏,就是1,否则是一个小数
						
						if(moveX > 0){
							index = Math.ceil(index);//返回大于或等于index的最小整数
						}else if(moveX < 0){
							index = Math.floor(index);//返回小于或等于index的最大整数
						}
						ul.style.left = index * img.offsetWidth+"px"
					 */
					
				})
			}
		}
	</script>
</html>

2、组件化无缝滑屏轮播(用户可以通过指定参数来决定是否需要无缝功能)

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0" /> -->
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<meta name="format-detection" content="telephone=no,email=no"/>
		<title></title>
		<style type="text/css">
			*{margin: 0;padding: 0;}
			html,body{height: 100%;overflow: hidden;}
			#wrap{height: 100%;overflow: hidden;}
			#wrap .carouse_wrap > .list{list-style: none;overflow: hidden;position: absolute;}
			#wrap .carouse_wrap > .list > li{float: left;}
			#wrap .carouse_wrap > .list > li > a,#wrap .carouse_wrap > .list > li > a > img{display: block;}
			#wrap .carouse_wrap > .list > li > a > img{width: 100%;}
		</style>
	</head>
	<body>
		<div id="wrap"><!-- 用来布局的,包裹轮播图,设置轮播图在页面位置 -->
			<div class="carouse_wrap"  ><!-- 轮播容器 -->
			</div>
		</div>
	</body>
	<script type="text/javascript">			
		window.onload=function(){
			/* 全局禁用默认事件触发 */
			document.addEventListener("touchstart",function(ev){
				ev=event||ev;
				ev.preventDefault();
			});
			
			/* 动态生成轮播图 */
			let arr = ["img/01.jpg","img/02.jpg","img/03.jpg","img/04.jpg","img/05.jpg"];//模拟从后台获取的轮播图列表
			
			let carouse_wrap = document.querySelector(".carouse_wrap");//获取轮播容器
			
			if(carouse_wrap){//如果轮播存在
				
				/* 无缝1、复制数组 并确定用户是否需要无缝功能*/
				
				/* 
					看看<div class="carouse_wrap" needCarouse >,加没加needCarouse,如果加了,表示用户需要无缝功能,没加就是null表示不需要无缝
				 */
				let needCarouse = carouse_wrap.getAttribute("needCarouse");//判断用户是否需要无缝功能
				
				if(needCarouse!=null){/* 如果不是null,表示需要无缝功能 */
					let arrLength = arr.length;//保存当前数组的长度,因为复制数组会让数组长度改变
					
					arr = arr.concat(arr)//向arr数组后面添加数组arr,生成一个全新的数组,然后重新赋值给arr
				}

				/* dom结点 */
				let ul = document.createElement("ul");		//创建一个ul结点
				let style = document.createElement("style");//创建一个style结点
				let head = document.querySelector("head");	//获取head结点
				
				ul.classList.add("list")					//给创建的ul的class列表添加一个.list样式
				
				for(let i = 0;i<arr.length;i++){//遍历数组,有多少图片就添加多少轮播结构
					ul.innerHTML+='<li><a href="javascript:;"><img src="'+arr[i]+'" ></a></li>'
				}
				
				carouse_wrap.appendChild(ul)				//把ul添加到容器中
				
				/* (重点)给style结点添加样式,首先
					我们应该先确定单张图片的大小,这里我就直接用百分比让图片填满屏幕了
					那么,我们应该让ul的宽度正好容纳这些轮播图片,比如5张图片就是500%
					
					那么5张图片,每张就占ul的20%,5*20%=100%,正好填满ul
				 */
				style.innerHTML="#wrap .carouse_wrap > .list{width: "+arr.length*100+"%;}#wrap .carouse_wrap > .list > li{width: "+100/arr.length+"%;}"
				
				head.appendChild(style)//将style结点添加到head中
				
				/* 最后,因为每个li都设置的定位,容器就没有东西撑开造成高度塌陷,我们只需要让其等于图片高度即可 */
				let img = document.querySelector("#wrap .carouse_wrap > .list > li:nth-of-type(1) > a > img");
				
				let timer=setTimeout(function(){/* 因为js代码执行很快,页面没渲染好就获取offsetHeight会获取不到,等100ms就可以了 */
					carouse_wrap.style.height=img.offsetHeight+"px"
				},100)
				clearTimeout(timer)//清除
				
				/* ==================创建轮播完================= */
				/* ==================滑屏======================= */
				let ElStartX = 0;	//元素当前位置
				let startX = 0;		//记录手点击起始位置
				let moveX = 0;		//记录手指滑动距离
				let endX = 0;		//记录手指抬起时位置
				let index = 0;		//记录当前轮播的下标
				/* 手指点击屏幕事件 获取手指和当前元素位置*/
				carouse_wrap.addEventListener("touchstart",function(ev){
					ev = event||ev;
					ElStartX = ul.offsetLeft;//获取元素当前位置
					startX = ev.changedTouches[0].clientX;//获取手指点击位置
					ul.style.transition="none";					//清除过渡,在手指抬起事件中绑定,这里要清掉,因为影响滑屏体验
					
					/* ===========无缝滑屏2======== */
					if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
						
						if(index===0){/* 如果是第一个数组第一张 */
							moveX = 0;										//重新定位需要清除刚刚算出来的滑动距离
							index=arr.length/2								//如果当前是第一张轮播图让index瞬间变为第二个数组的第一张
							ElStartX=-index * img.offsetWidth;				//起始位置变为第二个数组第一张
							ul.style.left = -index * img.offsetWidth+"px";	//ul偏移到第二个数组第一张
						}else if(index===(arr.length-1)){/* 如果是第二个数组最后一张 */					
							index=arr.length/2-1							//让index瞬间变为第一个数组最后一张
							ElStartX=-index * img.offsetWidth;				//起始位置变为第一个数组最后一张
							ul.style.left = -index * img.offsetWidth+"px";	//偏移到第一个数组最后一张
						}else{/* 如果不是第一和最后一张,普通的获取值即可 */
							ElStartX = ul.offsetLeft;//获取元素当前位置
						}
						
					}else{/* 是null表示不需要 */
						ElStartX = ul.offsetLeft;//获取元素当前位置
					}
					
					
				})
				/* 手指移动事件 让元素跟随手指移动*/
				carouse_wrap.addEventListener("touchmove",function(ev){
					ev = ev||event;
					let nowX = ev.changedTouches[0].clientX;	//获取滑动时的位置
					moveX = nowX - startX;						//获取滑动距离
					ul.style.left = ElStartX + moveX + "px";	//让ul跟随手指偏移
				})
				/* 手指抬起事件 判断移动距离,如果超过100px的距离,就让轮播跳转到下一张或上一张,第一张和最后一张怎么滑都会回到原来的位置*/
				carouse_wrap.addEventListener("touchend",function(ev){
					ev = ev||event;
					
					/* 无缝滑屏3,改改逻辑 */
					if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
						if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
							index--;
						}else if(moveX < 0 && moveX <= -100){
							index++;
						}
					}else{
						if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
							index===0?index=0:index--;		//如果index=0了就让index=4,否则就自减
						}else if(moveX < 0 && moveX <= -100){
							index===4?index=4:index++;
						}
					}
					
					ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
					
					ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
				})
			}
		}
	</script>
</html>

3、组件化自动轮播功能,用户可选功能

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0" /> -->
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<meta name="format-detection" content="telephone=no,email=no"/>
		<title></title>
		<style type="text/css">
			*{margin: 0;padding: 0;}
			html,body{height: 100%;overflow: hidden;}
			#wrap{height: 100%;overflow: hidden;}
			#wrap .carouse_wrap > .list{list-style: none;overflow: hidden;position: absolute;}
			#wrap .carouse_wrap > .list > li{float: left;}
			#wrap .carouse_wrap > .list > li > a,#wrap .carouse_wrap > .list > li > a > img{display: block;}
			#wrap .carouse_wrap > .list > li > a > img{width: 100%;}
		</style>
	</head>
	<body>
		<div id="wrap"><!-- 用来布局的,包裹轮播图,设置轮播图在页面位置 -->
			<div class="carouse_wrap" needCarouse needAutoCarouse ><!-- 轮播容器 -->
			</div>
		</div>
	</body>
	<script type="text/javascript">			
		window.onload=function(){
			/* 全局禁用默认事件触发 */
			document.addEventListener("touchstart",function(ev){
				ev=event||ev;
				ev.preventDefault();
			});
			
			/* 动态生成轮播图 */
			let arr = ["img/01.jpg","img/02.jpg","img/03.jpg","img/04.jpg","img/05.jpg"];//模拟从后台获取的轮播图列表
			
			let carouse_wrap = document.querySelector(".carouse_wrap");//获取轮播容器
			
			if(carouse_wrap){//如果轮播存在
				
				/* 无缝1、复制数组 并确定用户是否需要无缝功能*/
				
				/* 
					看看<div class="carouse_wrap" needCarouse >,加没加needCarouse,如果加了,表示用户需要无缝功能,没加就是null表示不需要无缝
				 */
				let needCarouse = carouse_wrap.getAttribute("needCarouse");//判断用户是否需要无缝功能
				
				if(needCarouse!=null){/* 如果不是null,表示需要无缝功能 */
					let arrLength = arr.length;//保存当前数组的长度,因为复制数组会让数组长度改变
					
					arr = arr.concat(arr)//向arr数组后面添加数组arr,生成一个全新的数组,然后重新赋值给arr
				}
				
				/* &&&&&&&&&&&&&自动轮播1、&&&&&&&&&&&&&&&& */
				let needAutoCarouse = carouse_wrap.getAttribute("needAutoCarouse");/* 如果有此参数,表示用户开启自动轮播 */
				if(needAutoCarouse!=null){
					let AutoTimer = 0;//用来保存自动轮播时间函数id
					AutoCarouse();	  //自动轮播函数
				}
				
				/* dom结点 */
				let ul = document.createElement("ul");		//创建一个ul结点
				let style = document.createElement("style");//创建一个style结点
				let head = document.querySelector("head");	//获取head结点
				
				ul.classList.add("list")					//给创建的ul的class列表添加一个.list样式
				
				for(let i = 0;i<arr.length;i++){//遍历数组,有多少图片就添加多少轮播结构
					ul.innerHTML+='<li><a href="javascript:;"><img src="'+arr[i]+'" ></a></li>'
				}
				
				carouse_wrap.appendChild(ul)				//把ul添加到容器中
				
				/* (重点)给style结点添加样式,首先
					我们应该先确定单张图片的大小,这里我就直接用百分比让图片填满屏幕了
					那么,我们应该让ul的宽度正好容纳这些轮播图片,比如5张图片就是500%
					
					那么5张图片,每张就占ul的20%,5*20%=100%,正好填满ul
				 */
				style.innerHTML="#wrap .carouse_wrap > .list{width: "+arr.length*100+"%;}#wrap .carouse_wrap > .list > li{width: "+100/arr.length+"%;}"
				
				head.appendChild(style)//将style结点添加到head中
				
				/* 最后,因为每个li都设置的定位,容器就没有东西撑开造成高度塌陷,我们只需要让其等于图片高度即可 */
				let img = document.querySelector("#wrap .carouse_wrap > .list > li:nth-of-type(1) > a > img");
				
				let timer=setTimeout(function(){/* 因为js代码执行很快,页面没渲染好就获取offsetHeight会获取不到,等100ms就可以了 */
					carouse_wrap.style.height=img.offsetHeight+"px"
				},100)
				clearTimeout(timer)//清除
				
				/* ==================创建轮播完================= */
				/* ==================滑屏======================= */
				let ElStartX = 0;	//元素当前位置
				let startX = 0;		//记录手点击起始位置
				let moveX = 0;		//记录手指滑动距离
				let endX = 0;		//记录手指抬起时位置
				let index = 0;		//记录当前轮播的下标
				/* 手指点击屏幕事件 获取手指和当前元素位置*/
				carouse_wrap.addEventListener("touchstart",function(ev){
					ev = event||ev;
					/* &&&&&&&&&&&&自动轮播2&&&&&&&&&&&&&&& */
					if(needAutoCarouse!=null){
						clearInterval(AutoTimer)//点击时清除自动轮播
					}
					
					ElStartX = ul.offsetLeft;//获取元素当前位置
					startX = ev.changedTouches[0].clientX;//获取手指点击位置
					ul.style.transition="none";					//清除过渡,在手指抬起事件中绑定,这里要清掉,因为影响滑屏体验
					
					/* ===========无缝滑屏2======== */
					if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
						moveX = 0;
						if(index===0){/* 如果是第一个数组第一张 */
							index=arr.length/2								//如果当前是第一张轮播图让index瞬间变为第二个数组的第一张
							ElStartX=-index * img.offsetWidth;				//起始位置变为第二个数组第一张
							ul.style.left = -index * img.offsetWidth+"px";	//ul偏移到第二个数组第一张
						}else if(index===(arr.length-1)){/* 如果是第二个数组最后一张 */					
							index=arr.length/2-1							//让index瞬间变为第一个数组最后一张
							ElStartX=-index * img.offsetWidth;				//起始位置变为第一个数组最后一张
							ul.style.left = -index * img.offsetWidth+"px";	//偏移到第一个数组最后一张
						}else{/* 如果不是第一和最后一张,普通的获取值即可 */
							ElStartX = ul.offsetLeft;//获取元素当前位置
						}
						
					}else{/* 是null表示不需要 */
						ElStartX = ul.offsetLeft;//获取元素当前位置
					}
					
					
				})
				/* 手指移动事件 让元素跟随手指移动*/
				carouse_wrap.addEventListener("touchmove",function(ev){
					ev = ev||event;
					let nowX = ev.changedTouches[0].clientX;	//获取滑动时的位置
					moveX = nowX - startX;						//获取滑动距离
					ul.style.left = ElStartX + moveX + "px";	//让ul跟随手指偏移
				})
				/* 手指抬起事件 判断移动距离,如果超过100px的距离,就让轮播跳转到下一张或上一张,第一张和最后一张怎么滑都会回到原来的位置*/
				carouse_wrap.addEventListener("touchend",function(ev){
					ev = ev||event;
					
					/* 无缝滑屏3,改改逻辑 */
					if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
						if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
							index--;
						}else if(moveX < 0 && moveX <= -100){
							index++;
						}
					}else{
						if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
							index===0?index=0:index--;		//如果index=0了就让index=4,否则就自减
						}else if(moveX < 0 && moveX <= -100){
							index===4?index=4:index++;
						}
					}
					
					ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
					
					ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
					
					/* &&&&&&&&&&&&&自动轮播3&&&&&&&&&&&&&&&& */
					if(needAutoCarouse!=null){
						AutoCarouse();//手指抬起时,重新启动自动轮播
					}
					
				})
				function AutoCarouse(){
					AutoTimer = setInterval(function(){
						if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
							
							if(index===arr.length-1){/* 如果是第二个数组最后一张 */
								ul.style.transition="none";//设置动画,在手指抬起时才设置				
								index=arr.length/2-1							//让index瞬间变为第一个数组最后一张
								ul.style.left = -index * img.offsetWidth+"px";	//偏移到第一个数组最后一张
							}
							setTimeout(function(){
								index++
								ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
								ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
							},500)
						}else{
								index===arr.length-1?index=0:index++;
								ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
								ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
						}
					},1000)
				}
			}
		}
	</script>
</html>

二、使用less来rem适配

首先你得了解如何适配
设计稿尺寸为1080

在这里插入图片描述
在这里插入图片描述

1、新建less文件使用考拉打包

在这里插入图片描述

//css reset
html,body,h1,h2,h3,h4,h5,p,a,img,span,div,input,form,ul{margin: 0;padding: 0;}
html,body{height: 100%;overflow: hidden;}
ul{list-style: none;}
a{text-decoration: none;display: block;}
img{display: block;}
a,input,button{-webkit-tap-highlight-color: rgba(0,0,0,0);outline: none;border:0;}//禁用这3个元素的选中高亮显示
button{-webkit-appearance: none;}//禁用button的特殊样式

//首先,我们font-size的值是动态的那么1rem也是动态的,我这里通常1rem就是视图尺寸的1/16
//所以我们只需要让设计图尺寸1080/16rem,就可以得到设计图对应当前手机的rem尺寸,
//16rem是当前屏幕的像素大小,1080是设计图大小,1080/16rem,就可以获取到设计图对应到当前屏幕的一个比例
@rem:1080/16rem;
#wrap{
	height: 100%;
	overflow: auto;
	.head{
		position: absolute;
		width: 100%;
		height: 100px;
		background-color: pink;
		.logo {
			img{
				/* 	方法一
					适配logo大小,首先我们将屏幕分成了16rem,
					而设计图大小为1080,logo大小240,240/1080=0.222222
					0.222222*16rem=3.555555555555556rem
				 */
				// width: 3.555555555555556rem; 很麻烦有没有
				
				/* 方法2
					图片尺寸240,@rem是当前设计图占多少份rem
					240/@rem=相应适配的rem值
				 */
				width:240/@rem;/* 240/67.5个rem,就是当前屏幕适配的rem */
			}
		}
	}
}

2、页面引入

在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title></title>
		<link rel="stylesheet" type="text/css" href="assets/css/index.css"/>
	</head>
	<body>
		<div id="wrap">
			<div class="head"><!-- 头部组件 -->
				<div class="head-top"><!-- 头部组件的上面部分 -->
					<h1 class="logo">
						<a href="javascript:;">
							<img src="assets/img/logo.png" >
						</a>
					</h1>
				</div>
				<div class="head-bottom"><!-- 头部组件下面的导航部分 -->
					
				</div>
			</div>
				
		</div>
	</body>
	<script type="text/javascript">
		window.onload=function(){
			/* 全局禁用默认事件 */
			document.addEventListener("touchstart",function(ev){
				ev = ev||event;
				ev.preventDefault();
			});
			/* 获取适配 */
			(function(){
				let style = document.createElement("style");//创建style结点
				let width = document.documentElement.clientWidth/16;//让widht为视口的16分之一
				style.innerHTML="html{font-size:"+width+"px !important}";//设置根标签字体大小
				document.head.appendChild(style);//将其添加到head
			})();
		}
	</script>
</html>

在这里插入图片描述在这里插入图片描述

三、尚硅谷谷粒音乐实战,b站搜就有视频和配套资源

1、工具类

/* 专门用来给node节点改变className属性的 */
(function(w){
	w.tools={};//暴露此对象,给window,同此对象来调用方法
	
	tools.addClass=function(node,className){
		let reg = new RegExp("\\b"+className+"\\b");//正则表达式,匹配所有className
		if(!reg.test(node.className)){
			node.className+=(" "+className);
		}
	}
	tools.removeClass=function(node,className){
		if(node.className){
			let reg = new RegExp("\\b"+className+"\\b");
			let classes = node.className;
			node.className = classes.replace(reg,"");
			if(/^\s*$/g.test(node.className)){
				node.removeAttribute("class");
			}
		}else{
			node.removeAttribute("class")
		}
	}
})(window)

2、无缝轮播

/* 动态生成轮播图 */
(function(w){
	w.carouse={};
	carouse.initCarouse=function(a){
		let arr = a;//模拟从后台获取的轮播图列表
		
		let carouse_wrap = document.querySelector(".carouse_wrap");//获取轮播容器
		
		if(carouse_wrap){//如果轮播存在
			
			/* 无缝1、复制数组 并确定用户是否需要无缝功能*/
			
			/* 
				看看<div class="carouse_wrap" needCarouse >,加没加needCarouse,如果加了,表示用户需要无缝功能,没加就是null表示不需要无缝
			 */
			let needCarouse = carouse_wrap.getAttribute("needCarouse");//判断用户是否需要无缝功能
			
			if(needCarouse!=null){/* 如果不是null,表示需要无缝功能 */
				let arrLength = arr.length;//保存当前数组的长度,因为复制数组会让数组长度改变
				
				arr = arr.concat(arr)//向arr数组后面添加数组arr,生成一个全新的数组,然后重新赋值给arr
			}
			
			/* &&&&&&&&&&&&&自动轮播1、&&&&&&&&&&&&&&&& */
			let needAutoCarouse = carouse_wrap.getAttribute("needAutoCarouse");/* 如果有此参数,表示用户开启自动轮播 */
			if(needAutoCarouse!=null){
				let AutoTimer = 0;//用来保存自动轮播时间函数id
				AutoCarouse();	  //自动轮播函数
			}
			
			/* dom结点 */
			let ul = document.createElement("ul");		//创建一个ul结点
			let style = document.createElement("style");//创建一个style结点
			let head = document.querySelector("head");	//获取head结点
			
			ul.classList.add("list")					//给创建的ul的class列表添加一个.list样式
			ul.style.transform="translateZ(0)";			//开启3d硬件加速,只要开启3d就会跳过浏览器,使用硬件加载
			for(let i = 0;i<arr.length;i++){//遍历数组,有多少图片就添加多少轮播结构
				ul.innerHTML+='<li><a href="javascript:;"><img src="'+arr[i]+'" ></a></li>'
			}
			
			carouse_wrap.appendChild(ul)				//把ul添加到容器中
			
			/* (重点)给style结点添加样式,首先
				我们应该先确定单张图片的大小,这里我就直接用百分比让图片填满屏幕了
				那么,我们应该让ul的宽度正好容纳这些轮播图片,比如5张图片就是500%
				
				那么5张图片,每张就占ul的20%,5*20%=100%,正好填满ul
			 */
			style.innerHTML="#wrap .carouse_wrap > .list{width: "+arr.length*100+"%;}#wrap .carouse_wrap > .list > li{width: "+100/arr.length+"%;}"
			
			head.appendChild(style)//将style结点添加到head中
			
			/* 最后,因为每个li都设置的定位,容器就没有东西撑开造成高度塌陷,我们只需要让其等于图片高度即可 */
			let img = document.querySelector("#wrap .carouse_wrap > .list > li:nth-of-type(1) > a > img");
			
			let timer=setTimeout(function(){/* 因为js代码执行很快,页面没渲染好就获取offsetHeight会获取不到,等100ms就可以了 */
				carouse_wrap.style.height=img.offsetHeight+"px"
			},100)
			clearTimeout(timer)//清除
			
			/* ==================创建轮播完================= */
			/* ==================滑屏======================= */
			let ElStartX = 0;	//元素当前位置
			let startX = 0;		//记录手点击起始位置
			let moveX = 0;		//记录手指滑动距离
			let endX = 0;		//记录手指抬起时位置
			let index = 0;		//记录当前轮播的下标
			/* 防抖动
				判断用户首次滑屏方向
					x轴
						不管用户怎么滑都会抖
					y轴
						不管用户怎么滑都不会抖
			 */
			let startY = 0;		//记录y轴,用来防抖动
			let moveY = 0;		//防抖动
			let XOrY = true;//true表示x轴,false表示y轴
			let first = true;//true表示首次滑,false表示不是首次滑
			
			/* 手指点击屏幕事件 获取手指和当前元素位置*/
			carouse_wrap.addEventListener("touchstart",function(ev){
				ev = event||ev;
				/* &&&&&&&&&&&&自动轮播2&&&&&&&&&&&&&&& */
				if(needAutoCarouse!=null){
					clearInterval(AutoTimer)//点击时清除自动轮播
				}
				
				ElStartX = ul.offsetLeft;//获取元素当前位置
				startX = ev.changedTouches[0].clientX;//获取手指点击位置
				startY = ev.changedTouches[0].clientY;//获取y轴位置,防抖动
				ul.style.transition="none";					//清除过渡,在手指抬起事件中绑定,这里要清掉,因为影响滑屏体验
				
				/* ===========无缝滑屏2======== */
				if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
					moveX = 0;
					if(index===0){/* 如果是第一个数组第一张 */
						index=arr.length/2								//如果当前是第一张轮播图让index瞬间变为第二个数组的第一张
						ElStartX=-index * img.offsetWidth;				//起始位置变为第二个数组第一张
						ul.style.left = -index * img.offsetWidth+"px";	//ul偏移到第二个数组第一张
					}else if(index===(arr.length-1)){/* 如果是第二个数组最后一张 */					
						index=arr.length/2-1							//让index瞬间变为第一个数组最后一张
						ElStartX=-index * img.offsetWidth;				//起始位置变为第一个数组最后一张
						ul.style.left = -index * img.offsetWidth+"px";	//偏移到第一个数组最后一张
					}else{/* 如果不是第一和最后一张,普通的获取值即可 */
						ElStartX = ul.offsetLeft;//获取元素当前位置
					}
					
				}else{/* 是null表示不需要 */
					ElStartX = ul.offsetLeft;//获取元素当前位置
				}
				
				
			})
			/* 手指移动事件 让元素跟随手指移动*/
			carouse_wrap.addEventListener("touchmove",function(ev){
				ev = ev||event;
				
				if(!XOrY){//放抖动=========如果首次在y轴滑,不执行下面逻辑
					return;
				}
				
				let nowX = ev.changedTouches[0].clientX;	//获取滑动时的位置
				let nowY  = ev.changedTouches[0].clientY;	//防抖动,获取当前y轴位置
				
				moveX = nowX - startX;						//获取滑动距离
				moveY = nowY - startY;						//获取y轴滑动距离
				
				/* 防抖动
					判断用户首次滑屏方向
						x轴
							不管用户怎么滑都会抖
						y轴
							不管用户怎么滑都不会抖
				 */
				if(first){//如果是首次滑屏,判断是x轴滑还是y轴滑,不是首次就不在进行下面的判断
					//让first = false;表示不是首次滑动了
					first = false;
					if(Math.abs(moveY)>Math.abs(moveX)){//如果y滑动距离比x大,说明是上下滑不是左右滑
						XOrY = false;//表示首次滑屏为y轴
						return;//如果是y轴,就不让它执行下面的偏移
					}
				}
				ul.style.left = ElStartX + moveX + "px";	//让ul跟随手指偏移
				
			})
			/* 手指抬起事件 判断移动距离,如果超过100px的距离,就让轮播跳转到下一张或上一张,第一张和最后一张怎么滑都会回到原来的位置*/
			carouse_wrap.addEventListener("touchend",function(ev){
				ev = ev||event;
				/* 防抖动 让XOrY重新置为true,first也变为true表示首次默认x轴 */
				XOrY = true;
				first = true;
				/* 无缝滑屏3,改改逻辑 */
				if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
					if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
						index--;
					}else if(moveX < 0 && moveX <= -100){
						index++;
					}
				}else{
					if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
						index===0?index=0:index--;		//如果index=0了就让index=4,否则就自减
					}else if(moveX < 0 && moveX <= -100){
						index===4?index=4:index++;
					}
				}
				
				ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
				
				ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
				
				/* &&&&&&&&&&&&&自动轮播3&&&&&&&&&&&&&&&& */
				if(needAutoCarouse!=null){
					AutoCarouse();//手指抬起时,重新启动自动轮播
				}
				
			})
			function AutoCarouse(){
				AutoTimer = setInterval(function(){
					if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
						if(index===arr.length-1){/* 如果是第二个数组最后一张 */
							ul.style.transition="none";//设置动画,在手指抬起时才设置				
							index=arr.length/2-1							//让index瞬间变为第一个数组最后一张
							ul.style.left = -index * img.offsetWidth+"px";	//偏移到第一个数组最后一张
						}
						setTimeout(function(){
							index++
							ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
							ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
						},500)
					}else{
							index===arr.length-1?index=0:index++;
							ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
							ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
					}
				},1000)
			}
		}
	}
})(window)

3、用来继承的less

.clearfix{
	*zoom: 1;
	&:after{
		content: "";
		display: block;
		clear: both;
	}
}

4、混合less

.1-px(top,@color:black){
	position: relative;
	&::before{
		position: absolute;
		content: "";
		display: block;
		top: 0;
		width: 100%;
		height: 1px;
		background: @color;
		@media only screen and (-webkit-device-pixel-ratio:2){
			transform: scaleY(.5);
		}
		@media only screen and (-webkit-device-pixel-ratio:3){
			transform: scaleY(.33333333);
		}
	}
}
.1-px(bottom,@color:black){
	position: relative;
	&::before{
		position: absolute;
		content: "";
		display: block;
		bottom: 0;
		width: 100%;
		height: 1px;
		background: @color;
		@media only screen and (-webkit-device-pixel-ratio:2){
			transform: scaleY(.5);
		}
		@media only screen and (-webkit-device-pixel-ratio:3){
			transform: scaleY(.33333333);
		}
	}
}

5、轮播图less

#wrap{
	.carouse_wrap{
		> .list{
			list-style: none;
			overflow: hidden;
			position: relative;
			> li{
				float: left;
				> a{
					display: block;
					> img{
						display: block;
						width: 100%;
					}
				}
			}
		}
	} 
}

6、主体less

//css reset
html,body,h1,h2,h3,h4,h5,p,a,img,span,div,input,form,ul{margin: 0;padding: 0;}
html,body{height: 100%;overflow: hidden;}
ul{list-style: none;}
a{text-decoration: none;display: block;}
img{display: block;}
a,input,button{-webkit-tap-highlight-color: rgba(0,0,0,0);outline: none;border: 0;}//禁用这3个元素的选中高亮显示
button{-webkit-appearance: none;}//禁用button的特殊样式
.txt {/* 禁用长按文字选中功能 */
    -webkit-touch-callout:none;
    -webkit-user-select:none;
    -khtml-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    user-select:none;
}
//首先,我们font-size的值是动态的那么1rem也是动态的,我这里通常1rem就是视图尺寸的1/16
//所以我们只需要让设计图尺寸1080/16rem,就可以得到设计图对应当前手机的rem尺寸,
//16rem是当前屏幕的像素大小,1080是设计图大小,1080/16rem,就可以获取到设计图对应到当前屏幕的一个比例
@rem:1080/16rem;
@import 'mixin/1-px';
@import 'extend/clearfix';//清除浮动
#wrap{
	height: 100%;
	overflow: auto;
	background-color: #EEEEEE;
	.head{
		position: relative;
		width: 100%;
		height: 270/@rem;
		background-color: #232323;
		.head-top{
			height: 135/@rem;
			.logo {
				float: left;
				img{
					width:240/@rem;
					height: 88/@rem;
					padding: 26/@rem 17/@rem 21/@rem 17/@rem;//上右下左
					
				}
			}
			.menuBtn{
				float: left;
				width: 129/@rem;
				height: 135/@rem;
				background: url(../img/menuBtn.png) no-repeat;
				background-size: 82/@rem 233/@rem;
				background-position: center 16/@rem;
				&.active{
					background-position: center -120/@rem;
				}
			}
			.buttons{
				float: right;
				padding-top:21/@rem;
				a{
					float: left;
					width: 111/@rem;
					height: 78/@rem;
					line-height: 78/@rem;
					background-color: #690;
					color: #ccc;
					margin-right: 15/@rem;
					font-size: 42/@rem;
					text-align: center;
					border-radius: 8/@rem;
					&.search{
						width: 130/@rem;
						height: 88/@rem;
						color: #fff;
						margin-right: 30/@rem;
						margin-top: 3/@rem;
						font-weight: bold;
						border-radius:10/@rem;
					}
				}
			}
		}
		.head-bottom{
			height: 103/@rem;
			padding: 16/@rem;
			.search{
				input[type="text"]{
					box-sizing: border-box;
					width: 829/@rem;
					height: 103/@rem;
					background-color: #999;
					padding: 5/@rem 10/@rem;
					border:1px solid #5a5a5a;
					font-size: 41/@rem;
					color: #333;
					border-radius: 15/@rem 0 0 15/@rem;
				}
				input[type="button"]{
					box-sizing: border-box;
					width: 190/@rem;
					height: 103/@rem;
					background-color: #414040;
					font-size: 41/@rem;
					color: #fff;
					border-radius: 15/@rem;
				}
			}
		}
		.mask{
			.1-px(top,#6a6a6a);
			position: absolute;
			z-index: 2;
			top: 135/@rem;
			width: 100%;
			padding: 10/@rem 0;
			display: none;
			background-color: rgba(0,0,0,0.8);
			> li{
				float: left;
				width: 22.5%;
				height: 135/@rem;
				line-height: 135/@rem;
				font-size: 54/@rem;
				text-align: center;
				> a{
					color: white;
				}
			}
		}
	}
	.content{
		overflow-x:hidden ;
		overflow-y: scroll;
		// background: pink;
		position: absolute;
		top: 270/@rem;
		bottom: 0;
		left: 0;
		right: 0;
		.nav{
			.1-px(bottom);
			width: 100%;
			height: 177/@rem;
			box-sizing: border-box;
			background: #EEEEEE;
			padding: 31/@rem 0 14/@rem 0;
			.list{
				position: absolute;
				font-size: 0;
				white-space: nowrap;/* 重点,让宽度不一样的元素排成一行规范,让元素不换行 */
				float: left;/* 重点,让宽度不一样的元素排成一行规范,浮动起来才能让容器被不换行的元素撑开 */
				> li{
					display: inline-block;/* 重点,让宽度不一样元素排成一行,float不能用,容器宽度不够会自动换行 */
					height: 129/@rem;
					line-height: 129/@rem;
					padding: 0 38/@rem;
					font-size: 1rem;
					a{
						color: #020202;
					}
					&.active{
						background: #690;
						a{
							color: #fff;
						}
					}
				}
			}
		}
		.tap_wrap{
			width: 1046/@rem;
			background: #FFFFFF;
			overflow: hidden;
			margin: 0 auto;
			.tap_head{
				height: 135/@rem;
				line-height: 135/@rem;
				h2{
					float: left;
					font-size: 1rem;
				}
				span{
					float: right;
					font-size: 0.7rem;
				}
			}
			.tap_nav{
				position: relative;
				height: 105/@rem;
				line-height: 105/@rem;
				a{
					float: left;
					height: 105/@rem;
					width:  120/@rem;
					font-size: 44/@rem;
					text-align: center;
					color: #6b6b6b;
				}
				.smallG{
					position: absolute;
					left: 0;
					bottom: 10/@rem;
					width:120/@rem;
					height:9/@rem;
					background: #6f900d;
				}
			}
			.tap_content{
				&:extend(.clearfix all);
				width: 300%;
				position: relative;
				ul{
					float: left;
					&:extend(.clearfix all);//使用继承样式
					width: 33.3333333%;
					li{
						box-sizing: border-box;
						float: left;
						width: 506/@rem;
						margin: 8/@rem;
						padding: 5/@rem;
						font-size: 40/@rem;
						background-color: #efefef;
						color: #000;
						overflow: hidden;
						a{
							img{
								width: 100%;
							}
							span{
								display: block;
								overflow: hidden;
								text-overflow:ellipsis;
								white-space: nowrap;
							}
						}
						.tap_discuss{
							.right{
								float: left;
								margin-right: 30/@rem;
								vertical-align: middle;
								span:nth-child(1){
									vertical-align: middle;
									display: inline-block;
									height: .6rem;
									width: .8rem;
									background: url(../img/ice.png) no-repeat;
									margin-right: 5/@rem;
								}
							}
							.left{
								float: left;
								vertical-align: middle;
								span:nth-child(1){
									vertical-align: middle;
									display: inline-block;
									width: .8rem;
									height: .6rem;
									background: url(../img/ice.png) no-repeat;
									background-position:0rem -60/@rem;
									margin-right: 5/@rem;
								}
							}
						}
						
					}
				}
				.tap_loding{
					background: url(../img/loading.gif) no-repeat;
					height: 10rem;
					background-position: center;
				}
			}
		}
	}
}

7、页面

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title></title>
		<link rel="stylesheet" type="text/css" href="assets/css/index.css"/>
		<link rel="stylesheet" type="text/css" href="assets/css/carouse/carouse.css"/>
	</head>
	<body>
		<div id="wrap">
			<div class="head"><!-- 头部组件 -->
				<div class="head-top"><!-- 头部组件的上面部分 -->
					<h1 class="logo"><!-- logo -->
						<a href="javascript:;">
							<img src="assets/img/logo.png" >
						</a>
					</h1>
					<a href="javascript:;" class="menuBtn"><!-- 面包屑导航 -->
					</a>
					<div class="buttons">
						<a href="javascript:;" class="search">搜索</a>
						<a href="javascript:;">登陆</a>
						<a href="javascript:;">注册</a>
					</div>
				</div>
				<div class="head-bottom"><!-- 头部组件下面的导航部分 -->
					<div class="search">
						<input type="text" placeholder="点我" />
						<input type="button" value="搜索" />
					</div>
				</div>
				<ul class="mask">
					<li>
						<a href="javascript:;">首页</a>
					</li>
					<li>
						<a href="javascript:;">MV</a>
					</li>
					<li>
						<a href="javascript:;">约旦</a>
					</li>
					
					<li>
						<a href="javascript:;">v榜</a>
					</li>
					<li>
						<a href="javascript:;">音乐</a>
					</li>
					
					<li>
						<a href="javascript:;">商城</a>
					</li>
					<li>
						<a href="javascript:;">节目</a>
					</li>
					
					<li>
						<a href="javascript:;">饭团</a>
					</li>
					<li>
						<a href="javascript:;">咨询</a>
					</li>
					
					<li>
						<a href="javascript:;">我的家</a>
					</li>
					<li>
						<a href="javascript:;">APP下载</a>
					</li>
					<li>
						<a href="javascript:;">热门引用</a>
					</li>
				</ul>
			</div>
			<div class="content">
				<div class="nav">
					<ul class="list txt">
						<li class="active">
							<a href="javascript:;">首页</a>
						</li>
						<li>
							<a href="javascript:;">MV</a>
						</li>
						<li>
							<a href="javascript:;">约旦</a>
						</li>
						
						<li>
							<a href="javascript:;">v榜</a>
						</li>
						<li>
							<a href="javascript:;">音乐</a>
						</li>
						
						<li>
							<a href="javascript:;">商城</a>
						</li>
						<li>
							<a href="javascript:;">节目</a>
						</li>
						
						<li>
							<a href="javascript:;">饭团</a>
						</li>
						<li>
							<a href="javascript:;">咨询</a>
						</li>
						
						<li>
							<a href="javascript:;">我的家</a>
						</li>
						<li>
							<a href="javascript:;">APP下载</a>
						</li>
						<li>
							<a href="javascript:;">热门引用</a>
						</li>
					</ul>
				</div>
				<div class="carouse_wrap" needCarouse needAutoCarouse ><!-- 轮播容器 -->
				</div>
				<div class="tap_wrap"><!-- tap选项卡 -->
					<div class="tap_head"><!-- tap头信息 -->
						<h2>MV主播</h2>
						<span>更多&gt;</span>
					</div>
					<div class="tap_nav"><!-- tap导航 -->
						<a href="javascript:;">全部</a>
						<a href="javascript:;">内地</a>
						<a href="javascript:;">港台</a>
						<a href="javascript:;">欧美</a>
						<a href="javascript:;">韩国</a>
						<a href="javascript:;">日本</a>
						<span class="smallG"></span>
					</div>
					<div class="tap_content"><!-- tap内容 -->
						<ul class="tap_loding"></ul>
						<ul>
							<li>
								<a href="javascript:;">
									<img src="assets/img/a.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/b.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/c.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/d.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/e.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/f.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
						</ul>
						<ul class="tap_loding"></ul>
					</div>
				</div>
				<div class="tap_wrap"><!-- tap选项卡 -->
					<div class="tap_head"><!-- tap头信息 -->
						<h2>MV主播</h2>
						<span>更多&gt;</span>
					</div>
					<div class="tap_nav"><!-- tap导航 -->
						<a href="javascript:;">全部</a>
						<a href="javascript:;">内地</a>
						<a href="javascript:;">港台</a>
						<a href="javascript:;">欧美</a>
						<a href="javascript:;">韩国</a>
						<a href="javascript:;">日本</a>
						<span class="smallG"></span>
					</div>
					<div class="tap_content"><!-- tap内容 -->
						<ul class="tap_loding"></ul>
						<ul>
							<li>
								<a href="javascript:;">
									<img src="assets/img/a.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/b.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/c.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/d.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/e.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
							<li>
								<a href="javascript:;">
									<img src="assets/img/f.jpg" />
									<span>安联大厦块级父垃圾广告士大夫</span>
								</a>
								<div class="tap_discuss">
									<div class="right">
										<span></span>
										<span>2000</span>
									</div>
									<div class="left">
										<span></span>
										<span>6</span>
									</div>
								</div>
							</li>
						</ul>
						<ul class="tap_loding"></ul>
					</div>
				</div>
			</div>	
		</div>
	</body>
	<script src="assets/js/tools.js" type="text/javascript" charset="utf-8"></script><!-- 操作ClassName -->
	<script src="assets/js/Carouse.js" type="text/javascript" charset="utf-8"></script><!-- 无缝滑屏轮播 -->
	<script type="text/javascript">
		window.onload=function(){
			/* 全局禁用默认事件 */
			document.addEventListener("touchstart",function(ev){
				ev = ev||event;
				ev.preventDefault();
			});
			
			/* 无缝轮播 */
			carouse.initCarouse(["assets/img/1.jpg","assets/img/2.jpg","assets/img/3.jpg","assets/img/4.jpg","assets/img/5.jpg"]);
			
			/* 获取适配 */
			(function(){
				let style = document.createElement("style");//创建style结点
				let width = document.documentElement.clientWidth/16;//让widht为视口的16分之一
				style.innerHTML="html{font-size:"+width+"px !important}";//设置根标签字体大小
				document.head.appendChild(style);//将其添加到head
			})();
			
			/* ===================遮罩js=================== */
			
			let mask = document.querySelector("#wrap .head .mask");	
			let menuBtn = document.querySelector("#wrap .head .head-top .menuBtn");
			let flag = false;//用来标识遮罩按钮的状态
			CMCFMenuBtn();
			function CMCFMenuBtn(){
				menuBtn.addEventListener("touchstart",function(ev){
					ev= ev||event;
					flag = !flag;
					if(flag){
						tools.addClass(menuBtn,"active")//给menuBtn的className+上一个active
						mask.style.display="block";//菜单显示
					}else{
						tools.removeClass(menuBtn,"active");//移除active
						mask.style.display="none";//菜单隐藏
					}
					
					ev.stopPropagation();	//取消事件冒泡,避免点击menuBtn触发touchstart事件的时候,
											//触发下面document的touchstart事件
					ev.preventDefault();//记住每次阻止冒泡要重新禁用默认事件,因为全局的阻止默认事件,被阻止冒泡了
				})
				mask.addEventListener("touchstart",function(ev){
					ev = ev||event;
					ev.stopPropagation();/* 取消事件冒泡,避免点击遮罩的时候触发下面document的事件 */
					ev.preventDefault();
				})
				document.addEventListener("touchstart",function(ev){
					ev = ev||event;
					if(flag){
						mask.style.display="none";//菜单隐藏
						flag=!flag;
						tools.removeClass(menuBtn,"active");//移除active
					}			
				})
			}
			/* ==================表单js======================= */
			/* 实现点击文本框,让手机弹出输入法 */
			changeFocus();
			function changeFocus(){
				let inputText = document.querySelector("#wrap .head .head-bottom .search input[type='text']");
				inputText.addEventListener("touchstart",function(ev){
					ev= ev||event;
					inputText.focus();//让文本框获取焦点,输入法会弹出来
					ev.stopPropagation();//不要让事件穿透
					ev.preventDefault();
				})
				/* 点击空白区,让输入法收回 */
				document.addEventListener("touchstart",function(){
					inputText.blur();//移除当前元素所获得的键盘焦点
				})
			}
			/* =====================拖动导航js======================= */
			dragNav();
			function dragNav(){
				//滑屏区域
				let navArea = document.querySelector("#wrap .content .nav");
				//滑屏元素
				let nav_list = document.querySelector("#wrap .content .nav .list");
				let startX = 0;		//手指按下的位置
				let endX = 0;		//手指移开的位置
				let moveX = 0;		//手指移动的距离
				let ElStartX = 0;	//元素一开始的位置
				let transformX = 0;	//元素跟随手指移动的距离
				//元素最后的位置,用滑屏区域-滑屏元素
				let ElEndX = navArea.clientWidth-nav_list.offsetWidth;
				
				/* 快速滑屏需要的参数,实现用户突然加速滑动的良好体验
					通过判断用户是否在短时间内滑动一定量的距离,如果符合,进行快速滑屏
				 */
				let lastTime = 0;	//上次点击的时间
				let nowTime = 0;	//现在的时间
				let lastPoint = 0;	//上次手指位置(不是上次滑屏位置)
				let nowPoint = 0;	//现在位置
				let differenceTime = 0;//上次点击时间与当前时间的差
				let differencePoint = 0;//手指上次位置与当前位置的差
				navArea.addEventListener("touchstart",function(ev){
					ev = ev||event;
					let touchC=ev.changedTouches[0];
					
					nav_list.style.transition="none";//每次点击时清除动画
					startX = touchC.clientX;		 //获取手指初始位置
					ElStartX = nav_list.offsetLeft;	 //获取元素初始位置
					
					/* 快速滑屏 */
					lastTime = new Date().getTime();//设置上传点击时间为当前时间
					lastPoint = startX;				//设置上次点击位置为当前位置
					
					differencePoint = 0;
				})
				navArea.addEventListener("touchmove",function(ev){
					ev = ev||event;
					let touchC = ev.changedTouches[0];
					
					let nowX = touchC.clientX;			//获取当前手指位置
					moveX = nowX-startX;				//获取移动距离
					transformX = ElStartX + moveX;  //元素跟随手指移动距离
					
					
					/* 橡皮筋效果 */
					if(nav_list.offsetLeft>=0){//如果要小于元素最后的位置,就不要让元素继续走,有橡皮筋效果
						/* scale用来保存一个比例,实现我越滑,比例越小,移动距离越短,越难滑的效果
							document.documentElement.clientWidth为视口宽度
							transformX是手指滑动距离 两个值加起来就会越来越大
							clientWidth/(clientWidth+transformX)这个比例就会越来越小,如果给(clientWidth+transformX)*2就更小了
							
							这时让元素移动的距离*这个比例,就会越滑,移动距离越短
						 */
						let scale = document.documentElement.clientWidth/((document.documentElement.clientWidth+transformX)*2);
						transformX = ElStartX + moveX*scale;
					}else if(nav_list.offsetLeft<=ElEndX){//大于0就不要让其往前滑屏,有橡皮筋效果
						let scale = document.documentElement.clientWidth/(document.documentElement.clientWidth+transformX);
						transformX = ElStartX - moveX*scale;
					}
					
					//让元素跟随手指移动
					nav_list.style.left=transformX+'px';
					
					/* 快速滑屏 */
					nowTime = new Date().getTime();	//设置当前时间
					nowPoint = nowX;				//设置当前位置
					
					differencePoint = nowPoint - lastPoint;
					differenceTime = nowTime - lastTime;
					
					lastPoint = nowPoint;
					lastTime = nowTime;
				})
				navArea.addEventListener("touchend",function(ev){
					ev=ev||event;
					/* 快速滑屏 */
					let speed = differencePoint/differenceTime;//距离/时间=速度
					let targetX = transformX + speed*differencePoint;	   //快速滑屏偏移,让当前偏移+速度的50倍
					
					let time = Math.abs(speed)*0.2;				//保存时间,用于设置动画的时间
					time = time<1?1:time;						//让时间不能少于1
					
					if(Math.abs(speed)<0.1){//如果速度小于1
						time = 0;								//让time=0,轻轻滑动不需要动画
						targetX = transformX;					//targetX无需加快速滑屏偏移
					}
					
					let bsr="";//保存贝塞尔曲线
					/* 橡皮筋效果 */
					if(nav_list.offsetLeft>0 || differencePoint>10 ){//如果当前元素偏移>0,或者距离差>10
						targetX = 0;//让targetX=0
						bsr="cubic-bezier(.01,1.36,.46,1.46)";//设置一个贝塞尔曲线
					}else if(nav_list.offsetLeft <= ElEndX ||differencePoint<-10 ){//如果当前元素偏移<元素最后位置,或者距离差<-10
						targetX = ElEndX;//让偏移位置为最后位置
						bsr="cubic-bezier(.01,1.36,.46,1.46)";//设置贝塞尔曲线
					}
					nav_list.style.transition=time+"s "+bsr+" left";//放开一瞬间给贝塞尔曲线动画效果
					
					if(differencePoint!=0){/* 如果=0表示只是点击没有移动,不需要偏移 */
						nav_list.style.left=targetX+'px';//偏移targetX
					}
					
				})
			}
			/* ======================tap选项卡js===================== */
			tap();
			function tap(){
				let tap_wrap = document.querySelector("#wrap .content .tap_wrap");
				let tap_content_ul_all = document.querySelectorAll("#wrap .content .tap_wrap .tap_content");
				let tap_content_smallG_all = document.querySelectorAll("#wrap .content .tap_wrap .tap_nav .smallG");
				let arr=tap_wrap.querySelectorAll("#wrap .content .tap_wrap .tap_nav > a");//获取选项卡下所有导航
				for(let i = 0;i < tap_content_ul_all.length;i++){
					move(tap_content_ul_all[i],tap_content_smallG_all[i],arr.length);//给每个选项卡和对应小绿条添加移动逻辑
				}
				
				function move(content,smallG,length){
					content.style.left = -tap_wrap.offsetWidth+"px";//默认偏移

					let start = {x:0,y:0};//初始手指位置
					let ElStart = {x:0,y:0};//元素初始位置
					let xOrY = true;		//true表示为X轴滑动
					let first = true;		//判断用户是否第一次滑,true表示第一次
					let stop = false;		//决定用户当前能否触发事件
					let isFlag = true;		//判断用户是否划过2分之一
					smallG.index=0;			//初始化小绿下标
					
					content.addEventListener("touchstart",function(ev){
						ev = ev||event;
						xOrY = true;
						isFlag = true;
						if(stop){return;}
						touchC = ev.changedTouches[0];
						start.x = touchC.clientX;
						start.y = touchC.clientY;
						ElStart.x = content.offsetLeft;
						ElStart.y = content.offsetTop;
						stop = false;
						
						content.style.transition = "none";//清除动画效果
					})
					
					content.addEventListener("touchmove",function(ev){
						ev = ev||event;
						if(stop){return;}
						/* 防抖1,如果首次滑为y轴,不执行滑屏逻辑 */
						if(!xOrY){
							return;
						}
						
						touchC = ev.changedTouches[0];
						let now = {x:0,y:0};
						now.x = touchC.clientX;
						now.y = touchC.clientY;
						let difference = {x:now.x - start.x,y:now.y - start.y}//距离
						/* 防抖2,如果是首次就判断是滑的哪个轴 */
						if(first){
							first = false;//变为false表示不再是第一次滑
							if(Math.abs(difference.x) < Math.abs(difference.y)){//如果x的差<y的差,表示y轴滑
								xOrY = false;//false表示y轴
								return;//直接终止本次
							}
						}
						if(Math.abs(difference.x) >= tap_wrap.offsetWidth*1/3){//如果移屏超过2分之一就偏移到过渡动画
							let left = difference.x<0?-2:0;//如果difference.x<0表示左滑>0表示右滑
							content.style.transition = "1s left";
							content.style.left = left*tap_wrap.offsetWidth+"px";
							isFlag = false;//进入2分之一
							
							/* 过渡动画执行完毕,发送请求 */
							stop = true;//阻止用户的触屏事件逻辑
							content.addEventListener("transitionend",endFn);
							content.addEventListener("webkitTransitionEnd",endFn);
							/* 小绿条 */
							smallGMove(left);
						}else{
							content.style.left = ElStart.x + difference.x +"px";
						}
					})
					
					/* 小绿条移动 */
					function smallGMove(left){
						smallG.style.transition = "1s left";
						smallG.lastIndex = smallG.index;//记录当前索引
						if(left === 0 ){//等于0表示右滑
						
							if(smallG.index === 0){//如果等于0,就让小绿条去最后面
								smallG.index = length-1;
							}else{//不等于0就减一
								smallG.index--;
							}
						}else{//左滑
						
							if(smallG.index === length-1){//小绿条在最后面就去最前面
								smallG.index=0;
							}else{
								smallG.index++;
							}
						}
						
						smallG.style.left = smallG.index*smallG.offsetWidth+"px";
					}
					/* 动画执行完毕后,发送请求 */
					function endFn(){
						/* 先解绑事件 */
						content.removeEventListener("transitionend",endFn);
						content.removeEventListener("webkitTransitionEnd",endFn);
						let flag = "";//这个应该是全局的,代表当前请求回来的数据
						let timer = setTimeout(function(){
							flag =  "";/* 将你请求回来的数据替换 ,因为没有后端,就假装模拟一下*/
							
							if(Math.floor((Math.random()*3+1))===2){//有3分之1几率请求失败
								content.style.left = -1*tap_wrap.offsetWidth+"px";
								alert("请求失败");
								/* 小绿条回到上次位置 */
								smallG.index= smallG.lastIndex;
								smallG.style.left = smallG.index*smallG.offsetWidth+"px";
								stop = false;
							}else{//请求成功
								content.style.transition = "none";
								content.style.left = -1*tap_wrap.offsetWidth+"px";
								stop = false;
							}
						clearTimeout(timer)
						},100)
						
					}
					
					content.addEventListener("touchend",function(ev){
						ev = ev||event;
						if(stop){return;}
						touchC = ev.changedTouches[0];
						if(isFlag){//如果是true表示还得回到当前屏
							content.style.transition = "2s left";
							content.style.left = -tap_wrap.offsetWidth+"px";
							//如果回到当前屏依然可以让用户进行下次滑屏
						}else{//如果为false,表示已经滑屏成功,进入加载动画,不准继续滑屏
							stop = true;
							console.log(1)
						}
						xOrY = true;
						first = true;
						isFlag = true;
						// stop = false;
					})
				}
			}
		}
	</script>
</html>

Vue3移动端项目实战:用Vant快速搭一个‘类原生’体验的H5页面(附完整代码) 本文详细介绍了如何使用Vue3和Vant组件库快速搭建一个具有原生体验的移动端H5页面。通过实战案例,展示了项目初始化、核心页面结构搭建、性能优化等关键步骤,帮助开发者高效完成电商H5开发,提升用户体验和开发效率。 阅读详情

相关推荐

用面包板实测MOSFET:手把手教你测量跨导和开关时间

本文详细介绍了如何使用面包板、Arduino和示波器搭建测试平台,实测MOSFET的跨导和开关时间。通过分步测量流程和示波器技巧,帮助电子设计初学者深入理解MOSFET的动态特性,包括跨导计算、开关时间参数解析以及米勒平台现象分析。

beer8的博客 224

H5端的使用vant组件库

H5端的使用vant组件库

qq_43235503的博客 1021

QT绘制饼图+柱状图+折线图

使用qt绘制,折线图,饼图,柱状图,多柱状图

梅山 3879

html5组件库,资源 | 10套好用的前端框架、设计组件库推荐

No.1 Ant Design UI 框架 解析:蚂蚁金服出品,基于 ReactJS。一个服务于企业级产品的设计体系,支持桌面端、手机端。基于『确定』和『自然』的设计价值观,通过模块化的解决方案,让设计者专注于更好的用户体验。No.2 Element UI 框架 解析:饿了么出品,基于 VueJS、React、Angular。一套为开发者、设计师和产品经理准备的桌面端组件库。No.3 Boo...

weixin_29887021的博客 7420

Windows 11下manage-bde命令实战:BitLocker锁了别慌,手把手教你用命令行找回数据

本文详细介绍了在Windows 11系统下使用manage-bde命令解锁BitLocker加密驱动器的实战方法。通过命令行诊断、恢复密钥获取、解锁流程演示及高级故障排除,帮助用户在系统锁定后快速找回数据,特别适合IT技术人员和遇到紧急情况的用户。

weixin_30902251的博客 333

贝叶斯网络在R语言中的应用

本文将介绍如何在R语言中使用贝叶斯网络进行建模和推断,并提供相应的源代码示例。以上就是在R语言中使用贝叶斯网络进行建模和推断的基本步骤。通过构建贝叶斯网络模型并使用相应的函数,我们可以对变量之间的依赖关系进行建模、推断和预测。在建立了贝叶斯网络模型后,我们可以使用数据集来估计变量之间的条件概率。接下来,我们可以使用数据集来构建贝叶斯网络模型。除了进行推断,我们还可以使用贝叶斯网络模型进行预测。一旦我们获得了贝叶斯网络模型和条件概率表,我们就可以使用该模型进行推断。首先,我们需要安装并加载相关的R包。

CodeMaven的博客 1280

移动Web UI库(H5框架)有哪些,看这里就够了

前言今年上半年,项目组在项目开发的过程中建立了一套风格统一,组件丰富完善,命名统一规范的PC端UI库,适用于做大型站点,该UI库也是应用到了整个平台的项目中,在各个项目组中进行推广。因为项目的保密性,这里不方便给出实际项目,当然目前这套UI库也不是开源的。下半年开始,我们偏向做移动Web的同学也开始考虑要梳理出这样一套适用于移动端的UI库,与PC端UI库命名规范保持一致,便于项目组同学在PC项目和移

前端向朔 12万+

等保测评-瀚高数据库

一般适用于等保测评

m0_54146694的博客 1634

H5UI库和二维码

H5UI库 加密技术 二维码

m0_74331160的博客 1275

200Gb/s以上速率的通道信号完整性设计和优化经验(二)

为满足200Gb/s信号完整性需求,需综合优化PCB、连接器、封装及SERDES架构。关键措施包括:采用低粗糙度铜箔与低损耗材料降低传输线损耗(200G目标0.55–0.6dB/cm);通过背钻工艺控制残桩长度至4±2mil;缩减连接器焊盘残桩至600μm以内以消除谐振;封装层面推进跳层走线、低Dk/Df材料与可控SMT工艺;采用PAM4调制与基于ADC/DSP的混合信号架构实现高效均衡。先进CMOS工艺(如纳米片器件)支撑复杂数字处理,协同设计是突破速率瓶颈的核心。

小孟同学的博客 149

基于应用谱减法进行语音去噪的算法

在上述代码中首先通过读取语音信号和噪声信号,将两个信号都转换为频域信号,然后计算出语音信号在各频率下的功率谱和噪声信号在各频率下的功率谱,并基于此计算信噪比,接着根据信噪比计算出阈值,并将低于阈值的能量对应的频段进行清零操作,最终实现去噪处理,最后将处理后的信号转换回时域信号。该算法采用谱减法进行降噪处理,能有效地去除语音信号中的噪声,但是在实际应用中,该方法也存在一些问题,如会对语音信号的高频部分产生影响,所以需要在应用过程中进行适当的调整。

weixin_50547796的博客 193

超详细讲解H5移动端适配 —— 移动端适配方案

目前来讲这三种方案是现在用的最多的方案,它们都有各自的优缺点。

李水灵的博客 1万+

刷爆 Java 基础!1000 道经典面试题精解第一篇【序列化】

自定义序列化 / 反序列化的实现方式在实现接口的类中,手动重写和方法在方法内优先调用执行默认序列化逻辑;追加自定义逻辑(如敏感数据加密、临时字段赋值、兼容旧版本数据等)。// 序列化ID,保证兼容性// 敏感字段,默认不序列化,自定义处理// 自定义序列化// 执行默认序列化:写入username// 自定义逻辑:密码加密后写入// 自定义反序列化// 执行默认反序列化:读取username// 自定义逻辑:读取加密密码并解密// 模拟加密/解密工具方法。

七叔的博客 193

搭建一个vue-cli的移动端H5开发模板

简介 vue-mobile 是是基于 vue-cli 实现的移动端 H5 开发模板,其中已经搭建好基本的开发框架,可帮助您实现快速开发。 技术栈:vue + vux + axios + less 源码地址:github.com/Michael-lzg… 功能 搭建项目目录 配置 css 预处理器 配置 UI 组件库 vux 解决移动端适配 配置页面路由缓存 axios 请求封装 ...

Michael_lzg的博客 2232

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

html5 移动端开发模板,搭建一个vue-cli的移动端H5开发模板

简介vue-mobile 是是基于 vue-cli 实现的移动端 H5 开发模板,其中已经搭建好基本的开发框架,可帮助您实现快速开发。技术栈:vue + vux + axios + less功能搭建项目目录配置 css 预处理器配置 UI 组件库 vux解决移动端适配配置页面路由缓存axios 请求封装工具类函数封装toast 组件封装dialog 组件封装底部导航组件封装列表页 demo表单页 ...

weixin_35681965的博客 1613

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

移动端 H5 rem 适配的数学逻辑

移动端H5 rem适配基于数学比例缩放原理,通过动态计算根元素字体大小实现响应式布局。核心公式为:html font-size = (设备宽度/设计稿宽度) × 基准值(如100px)。设计稿中的px值转换为rem只需除以基准值。实现时需JavaScript动态计算根字体大小,配合CSS预处理器简化单位转换。该方法能保持设计稿比例,适配各种屏幕尺寸,但需注意1px边框、文字大小等特殊处理。通过这套数学逻辑,可构建灵活、可维护的移动端适配方案。

m0_64344997的博客 823

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Vue移动端开发:如何快速搭建高质量的H5应用?

在当今移动优先的时代,高效开发H5应用已成为前端工程师的必备技能。Vue-H5-Template作为一个专为移动端优化的Vue模板,为你提供了一套完整的解决方案,让你能够快速构建出适配各种移动设备的H5应用。 ## 移动端开发面临的三大挑战 在开始使用Vue-H5-Template之前,让我们先了解移动端开发中常见的痛点: **1. 设备适配难题** 不同移动设备的屏幕尺寸、分辨率差异巨大,

gitblog_00832的博客 778

android h5 rem插件,H5 活动页之移动端 REM 布局适配方法

本文介绍的方案来源于一次 H5 活动的开发实践。 H5 DEMO 参考:bir2017拿到设计稿后,如何进行布局还原?如果只需要做非精确的响应式设计,那么使用媒体查询来实现就 OK 了。如果需要精确还原设计稿,则一般通过缩放来实现,常见的缩放方案有基于 viewport 和基于 rem 的布局适配方法。1 viewport 缩放方案在移动端,可以通过 viewport 缩放页面大小比率达到目的。简...

weixin_42501688的博客 216

移动端适配 rem flexible less 使用

html <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>test</title> <!-- <script src...

笔记库 776

vue移动端怎么设置页面高度_详解搭建一个vue-cli的移动端H5开发模板

简介vue-mobile 是是基于 vue-cli 实现的移动端 h5 开发模板,其中已经搭建好基本的开发框架,可帮助您实现快速开发。 技术栈:vue + vux + axios + less功能搭建项目目录配置 css 预处理器配置 ui 组件库 vux解决移动端适配配置页面路由缓存axios 请求封装工具类函数封装toast 组件封装dialog 组件封装底部导航组件封装列表页 demo表单页...

weixin_39630735的博客 425

TDesign Uniapp 组件库快速上手:从安装、easycom 自动注册到多端适配

本文是一份以 `tdesign-miniprogram` 仓库中 [TDesign Uniapp 快速上手文档](https://link.gitcode.com/i/0de1d72b66b8b4128f8f91057f84c925) 为核心展开的实战指南。TDesign 是腾讯开源的企业级设计体系,本仓库中的 `packages/tdesign-uniapp` 正是其适配 uni-app 的移动

gitblog_01414的博客 554

移动端rem-less适配。

由于现有布局flew,流式布局和响应式布局只能实现宽度的布局,没办法实现字体大小的自适应,这个时候使用rem-less来进行适配。 @charset "utf-8"; //rem适配方案不好维护 设备太多,更新太快 //根据less进行适配 //主流移动设备尺寸,只写了苹果的 @adapterDeviceList:1242px,1125px,1080px,750px,720px,640px,32...

weixin_42628334的博客 520

vue+vant 移动端H5 商城项目_01

一、 技术选型 组件 版本 说明 vue ^2.6.11 数据处理框架 vue-router ^3.5.3 动态路由 vant ^2.12.37 移动端UI axios ^0.24.0 前后端交互 amfe-flexible ^2.2.1 Rem 布局适配 postcss-pxtorem ^5.1.1 Rem 布局适配 less ^4.1.2 css编译 less-loader ^5.0.0 css编译 vue/cli ~4.5.0 项目脚手架 vu...

Gblfy_Blog 5025

移动web适配(rem)、less的使用

移动web适配(rem)、less的使用

weixin_72297531的博客 411

十、rem适配方案:用媒体查询+less+flexible.js搭建移动端等比缩放体系

用媒体查询+less+flexible.js搭建rem适配体系,750设计稿基准根字号75px,cssrem插件自动转单位,flexible.js动态设根字号实现等比缩放。TaoToken可辅助批量换算与断点生成,官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end

weixin_42601134的博客 9

如何用 lib-flexible 实现移动端H5页面适配

最近这几个星期在学到了移动端H5页面适配,以前根本没做过移动端网页,所以把我学到的小知识点写下来,也分享给前端新手们。 做移动端网页和pc端很大不同的便是现在移动端窗口分辨率繁多。 很多时候UI给的设计图只有一份,还是按照iphone6设计的,这就让前端适配其他例如6plus或安卓等其他移动端头疼。 还好,阿里巴巴2015年底公开了其成熟的适配方案,lib-flexible,至于其可靠性可参...

sunnyjingqi的博客 422
上一篇: 写web移动端如何用真机测试
下一篇: 不要进来看,这只是我为了以后方便复制,拿过来的myBatis的Mapper.xml文件
ydenergy_殷志鹏
博客等级 码龄7年 5887粉丝 543原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值