移动端开发

一、视口相关

当我们写完的html代码用浏览器的移动端打开的时候,会发现字体变小了,很模糊,甚至看不清楚,所以我们需要加上meta视口标签的配置,来改变这种情况。

<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/>

/**
	width=device-width 表示的当前视口宽度等于当前设备的宽度
	initial-scale=1表示的是当前缩放的是1,也就是没有缩放
	user-scalable=no:表示的是用户是否可以进行缩放,no表示否
*/

我们来思考一个问题,我们如何在不同的设备上来实现不同的布局呢?

上面说的这个问题就是响应式布局,那么响应式布局如何实现呢?首先我们能够想到的就是媒体查询的方式

<header>
//必须要保证设置了viewport
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/>
</header>
 <style>
	.box {
		width:400px;
		height:400px;
		background:#f1b0b7;
	}
	//媒体查询的方式
	@media all and (min-width:400px	) and (max-width:1000px){
		.box{
			background:#000;
		}
	}
</style>

像素比

像素比:物理像素/逻辑像素

屏幕:我们的屏幕就是一个一个的发光二极管组成的,比如我们的电脑的最高的分辨率是1920x1080那么屏幕上的发光二极管的数量就是1920x1080个。
那么物理像素就是1920x1080;而逻辑像素则是当我们调整我们电脑的分辨率,比如我调整我的电脑到1366x768,他就会通过多个发光二极管去显示一个物理像素,所以逻辑像素就是1366x768。这两个数值的比值就是像素比。

适配

1.vw、vh适配

在页面中的元素,其实是占用固定的比例,不管手机多大多小,都能完整的显示页面,并且没有结构上的差异。

移动端主要通过vm,和vh来实现适配

1vw = 屏幕宽度的百分之一; 1vh= 屏幕高度的百分之一;所以50vw等于屏幕宽度的一半

实际项目使用

给我一张设计稿 宽度是750px像素的,然后我们要去适配它,我们应该怎么去实现不同设备的适配呢?

比如这个设计稿中,搜索栏的宽度和高度分别是;100% 和94px:

<div class=search></div>
/**
	750px = 100vw 所以 1vw = 7.5px;
	94px = ?vw    ? = 94/7.5vw
*/
<style>
	.search{
		width:100vw;
		height:calc(94vw/7.5);
		background:#fff;
	}
</style>
//通过上面的计算我们可以发现搜索栏的高度应该是94/7.5vw;这样就是实现适配了。我们当然也可以计算出具体的值,但是没有必要,因为太麻烦了.

这种方式存在一个问题就是会大量的换算公式,比较麻烦,我们可以通过scss文件来解决这个问题

//scss.css
$vw = 7.5;

//使用方式,可以直接使用 `/` 进行计算
.search{
	width:100vw;
	height:94vw/$vw;
	background:#fff
}

2.em适配

em 相对于当前元素的font-size大小

看下面的例子:

<head>
	<style>
		.box{
			font-size:20px;
		}
		.main{
			//因为em是相对于自身的font-size来说的,但是自身的font-size也是em所以它会往上找;
			font-size:2em;//40pxx
			width:2em;//80px
			height:3em;//120px
		}
	</style>
</head>

<div class="box">
	<div class="main"></div>
</div>

3.rem适配

r:表示的是root 的意思,根元素,html;始终相对于根元素的font-size大小来计算;

rem 适配的基本原理: 是通过改变跟元素的font-size来实现的,我们来看下面的代码


	<head>
	<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/>
	<style>
		html{
			font-size:32px;
		}
		.box{
			width:5rem;
			height:3rem;
			background:#103433;
		}
	</style>
	
	<script>
		//我们不可能每次设备改变了都去手动修改根元素font-size的值。但是我们可以通过js动态的去修改:
		let rootEl = document.documentElement;
		let viewWidth = window.innerWidth;
		rootEl.style.fontSize = viewWidth/10 + 'px'
	</script>
</head>

<body>
<div class="box"></div>
</body>



接下来我们模拟一下实际项目开发中的适配场景:

/**
	首先我们假设我们把屏幕分成25rem ,也可以是其他rem 根据个人需要
	1.我们把屏幕分成25份 : html-font-size : width/25 等于 100vw/25 = 4vw;
	2.设计稿也要分成25份 : 750/25 = 30px  所以1rem = 30px 
	3.假设我们有一个元素.box 宽度是80px,我们该如何计算它的rem????
		80px = ?rem  因为 1rem = 30px 所以 ? = 80/30rem;
	4.同时我们还需要修改上面的js计算的font-size为分成25份的大小
		let rootEl = document.documentElement;
		let viewWidth = window.innerWidth;
		rootEl.style.fontSize = viewWidth/25 + 'px'
	5.我们在scss文件中设置元素的宽度:
		$rem = 30;
		
		.box{
			width:80rem/$rem;
		}
*/

4.flex布局

flex 布局很经典,主要是子组件身上的事件,现在先不记录,用的时候再说。

二、移动端事件

1.移动端的鼠标事件

大家都知道在pc端有鼠标事件,但是在移动端我们都是用手指点击,那么手指的点击事件肯定也有对应的方法,并且移动端同样具有pc端的鼠标点击事件:

pc端鼠标点击事件:

  • mousedown:鼠标在元素身上按下;
  • mousemove:鼠标在元素身上移动;
  • mouseup:鼠标在元素身上抬起;

移动端手指点击事件:

  • touchstart : 手指在元素身上按下;
  • touchmove: 手指在屏幕中移动(在此之前,手指必须在元素身上按下,不管移动的时候手指是否在元素身上);
  • touchend : 手指在屏幕中抬起(在此之前,手指必须在元素身上按下);

移动端也支持鼠标事件,但是鼠标事件的执行会被延迟一段时间:

移动端在点击元素的时候,会立即执行元素身上的touch事件,同时记录点击的坐标点等touch事件执行完毕之后,会再一次在坐标中查找元素,并且执行元素身上的mouse事件 300ms; mouse事件和touch事件可以不在同一个元素身上,只在乎这两个元素位置是否相同,最典型的bug就是会导致移动端的点透事件

什么是点透事件?

//点透事件就是点击一个div标签,然后会触发盒子里面的事件,下面我们看一下代码:
<div class='box'></div>
<a class='link' href='https://www.baidu.com'>百度</a>

<script>
	let box = document.querySelector(".box");
	
	/**
		针对点透事件的解决方案:
		1.尽量不要在移动端使用鼠标事件(包括a标签的使用)用js做跳转
		2.延迟执行touch事件里面的代码;
		3.阻止默认事件
	*/
	box.ontouched = function(ev){
		setTimeout(()=>{
			this.style.display = "none";
		},300);
		//ev.preventDefault();
	}
</script>

2.其他事件

  • changedTouches:[] 触发当前事件的手指列表;
  • targetTouches:[] 当前元素身上的手指列表;
  • touches:[] 当前屏幕中的手指列表;

实现下面一个需求:移动端拖拽的实现:

let box = document.querySelector('.box');
let startX,startY = 0;
box.ontouchstart = function(ev){
	let info = box.getBoundingClientRect();
	startX = info.left;
	startY = info.top;
	let touch = ev.changedTouches[0];
	oldX = touch.pageX;
	oldY = touch.pageY;
}
box.ontouchmove = functiono(ev){
	let touch = ev.changeTouches[0];
	let nowX = touch.pageX - oldX + startX;
	let nowY = touch.pageY - oldY + startY;
	box.style.transform = `translate(${nowX}px,${nowY}px)`;
	ev.preventDefault();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值