指屏幕对角线长度,单位是英寸(inch)。常见尺寸有:3.5寸、4.0寸、5.0寸、5.5寸、6.0寸等。备注:1英寸(inch)=2.54厘米(cm)
是指屏幕在:横向、纵向上的物理像素点(屏幕上微小的发光点)总数,一般用 n * m 表示。
例如:iPhone6 的屏幕分辨率为: 750 * 1334
常见手机分辨率
又称:屏幕像素密度,是指屏幕上每英寸里包含的物理像素点个数,单位是ppi(pixels per inch),其实这里还有另一个单位 dpi (dots per inch),两个值的计算方式都一样,只是使用的场景不同。
ppi主要用来衡量屏幕,
dpi主要用来衡量打印机、投影仪等。
又名:设备像素,物理像素是一个长度单位,单位是px,1个物理像素就是屏幕上的一个物理成像点,就是屏幕中一个微小的发光物理元器件(可简单理解为超级微小的灯泡),是屏幕能显示的最小粒度。屏幕的物理像素点数(分辨率)是手机屏幕的一个重要参数,由屏幕制造商决定,屏幕生产后无法修改。
例如iPhone6 横向上拥有的物理像素为750、纵向上拥有的物理像素为1334,用750*1334表示。
物理像素图示:
css像素又名:逻辑像素,css像素是一个抽象的长度单位,单位也是px,它是为Web开发者创造的,用来精确地度量Web页面上的内容大小。我们在编写css\js\less中所使用的都是css像素(可以理解为:“程序员像素”)。
思考︰我代码中所写的1px (css像素),到了屏幕上到底对应几个物理像素呢?是1个css像素就对应1个物理像素(“发光的灯泡")吗?要探讨这个对应关系,就要学习接下来的新概念:设备独立像素。
设备独立像素简称DIP或DP(device-independent pixel),又称:屏幕密度无关像素(它由设备决定,我们无法改变)。
引言:在没出现【高清屏】的年代,1个css像素对应1个物理像素,但自从【高清屏】问世,二者就不再是1对1的关系了。苹果公司在2010年推出了一种新的显示标准:在屏幕尺寸不变的前提下,把更多的物理像素点压缩至一块屏幕里,这样分辨率就会更高,显示效果就会更佳细腻。苹果将这种屏幕称为: Retina屏幕(又名:视网膜屏幕),与此同时推出了配备这种屏幕的划时代数码产品—iPhone4。
我们来看一个场景:
程序员写了: width=2px, height=2px的盒子,若1个css像素直接对应1个物理像素,由于 iPhone3G/S与iPhone4屏幕尺寸相同,但iPhone4的屏幕能容纳下更多的物理像素点,所以iPhone4的物理像素点比iPhone3G/S小很多,那么理论上这个盒子在 iPhone4屏幕上也就会比iPhone3G/S屏幕上小很多,而事实是 iPhone3G/S和 iPhone4下这个盒子是一样大的!!!,只不过 iPhone4更加细腻、清晰。如何做到的呢?这就要靠设备独立像素。
设备独立像素的出现,使得即使在【高清屏】上元素也可以拥有正常的尺寸,s让代码不受到设备的影响,它是设备厂商根据屏幕特性设置的,无法更改。
设备独立像素与物理像素关系:
设备独立像素与css像素关系:
像素比(dpr,device pixel ratio):单一方向上,【物理像素】和【设备独立像素】的比值。即:dpr = 物理像素 / 设备独立像素
在不考虑缩放
的情况下(理想状态下):
程序员写了一个width为100px的盒子,那么:
描述一下你的屏幕,现在以iPhone6为例,我们描述一下屏幕(横向上):
位图和矢量图
位图:又称点阵图形或栅格图像,是由n个的像素点(就是指位图的像素点,既不是物理像素,也不是css像素)组成的。放大后会失真。(常见:png、jpeg、jpg、gif),一般用PhotoShop等软件进行编辑。
矢量图:又称为面向对象图像或绘图图像,在数学上定义为一系列由线连接的点,放大后不会失真。(常见:svg),一般使用Adobe Illustrator,Sketch等软件进行编辑
位图像素也是一个长度单位,位图像素可以理解为位图中的一个“小格子”,是位图的最小单元。
注意:1个位图像素对应1个物理像素,图片才能得到完美清晰的展示。
具体编码时借助媒体查询:@media screen and (-webkit-min-device-pixel-ratio:x)
其实就是:假设将一个200*200px(这里指的是位图的像素点)的位图图片放入200px*200px的css像素盒子(这里指的是css盒子的大小)中,根据分辨率和物理像素比所得到的dpr,决定将此200*200px的图片使用多少实际的物理像素点显示。如果dpr是1,那么就是1css像素=1设备独立像素=1物理像素,那么这个位图的像素点数量正好可以塞满实际的物理像素点。但是如果是dpr为2,那么就是1css像素=1设备独立像素=2物理像素,位图像素的数量明显不够塞满实际的物理像素,所以会模糊填充,这样就会造成不能充分的利用好这样的高清屏幕。但是不管是使用的1x图,还是2x图,最终看的效果的大小是一样的,只是使用的图片的位图数量不够,导致图片看起来可能会不清晰。
目前一般仅logo需要做高清显示,或提供svg格式logo即可解决问题,否则采用媒体查询:
/* 媒体查询的书写顺序也很重要 */
@media screen and (-webkit-min-device-pixel-ratio:2) {
.logo{
/* 可以直接使用content修改img标签中的src属性 */
content: url(../imgs/[email protected])
}
}
@media screen and (-webkit-min-device-pixel-ratio:3) {
.logo{
content: url(../imgs/[email protected])
}
}
在pc端,视口的默认宽度和浏览器窗口的宽度一致。在css标准文档中,视口也被称作:初始包含块,它是所有css百分比宽度推算的根源,在PC端可通过如下几种方式获取宽度:
console.log('最干净的显示区域', document.documentElement.clientWidth); // 常用
console.log('最干净的显示区域+滚动条', window.innerWidth);
console.log('最干净的显示区域+滚动条+浏览器边框', window.outerWidth);
console.log('与浏览器无关,当前设备显示分辨率横向的值', screen.width);
注意:PC端只有一种视口(不像移动端有2个视口),PC端缩放页面可以通过window.onresize = ()=>{} 监测到。
在移动端,浏览器厂商面临着一个比较大的问题:他们如何将数以万计甚至可以说是数以亿计的pc端网页完整的呈现在移动端设备上,并且不会出现横向滚动条呢?那就要引出移动端的三个概念:1.布局视口、2.视觉视口、3.理想视口。
为了解决早期的页面在手机上显示的问题,早期的时候我们这样做:pc端网页宽度一般都为:960px1024px这个范围,就算超出了该范围,960px~1024px这个区域也依然是版心的位置。
浏览器厂商针对移动端设备设计了一个容器,先用这个容器去承装PC端的网页,这容器的宽度一般是
980px,不同的设备可能有所差异,但相差并不大; 随后将这个容器等比例压缩到与手机等宽,这样就可以保证没有滚动条且能完整呈现页面,但是这样做依然有问题:网页内容被压缩的太小,严重影响用户体验。
移动端获取布局视口的方式,如下代码:
(注意:这在移动端使用此代码,获取的是布局视口,与在pc端使用此代码有所区别)
let layoutWidth = document.documentElement.clientWidth // (一般都是980px,iPad Pro是1024px)
注意:布局视口经过压缩后,横向的宽度用css像素表达就不再是375px了,而是980px,因为布局视口是被压缩,而不是截取(就是上面说的会将这个980px的容器等比例压缩到与手机等宽)。
不考虑缩放的情况下
,但在此布局视口中,是会发生缩放的DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Documenttitle>
<style>
* {
margin: 0;
padding: 0;
}
#info {
width: 980px;
background-color: pink;
/* 由于PC网页在移动端查看会压缩, 因此将字体放大 */
font-size: 50px;
}
style>
head>
<body>
<div id="info">div>
body>
<script>
// 获取移动端布局视口宽度
const layoutWidth = document.documentElement.clientWidth
const info = document.getElementById('info')
info.innerHTML = '您设备的布局视口宽度为' + layoutWidth + 'px(css像素)'
script>
html>
视觉视口就是用户可见的区域,它的绝对宽度永远和设备屏幕一样宽,但是这个宽度里所包含的css像素值是变化的,例如:一般手机会将980个css像素放入视觉视口中 (在用户不缩放页面的情况下,视觉视口大小=布局视口大小
),而 ipad Pro会将1024个css像素放入视觉视口中。
移动端获取视觉视口方式: window.innerWidth
(这里不要和PC端使用此代码作对比,这里就仅仅是表示移动端的特殊含义:获取视觉视口),不过在 Android2、 Opera mini、UC8中无法正确获取。(一般也不通过代码看视觉视口)
如果以iPhone6为例,描述一下屏幕(横向上):
与屏幕(设备独立像素,dp/dip)等宽的布局视口,称之为理想视口
,所以也可以说理想视口是一种标准:让布局视口宽与屏幕等宽(设备独立像素),靠meta标签实现。
设置理想视口的具体方法(这样设置后,不管是什么移动端设备,这个移动端设备的设备独立像素是多少,那么布局视口就是多少):
<meta name="viewport" content="width=device-width">
DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width">
<style>
* {
margin: 0;
padding: 0;
}
#info {
font-size: 50px;
width: 375px;
background-color: #bfa;
}
style>
head>
<body>
<div id="info">div>
body>
<script>
document.getElementById("info").innerHTML = '当前设备的布局视口宽度为: ' + document.documentElement.clientWidth;
script>
html>
不写meta标签(不符合理想视口标准)
写meta标签(符合理想视口标准):
放大时:
缩小时:
理解:pc端只有一种视口,pc端缩放时,比如:放大时,先把视口变小,然后元素按变小的视口排列,然后再把视口缩放成屏幕实际宽度,这样就达到了放大的效果。缩小时,先把视口变大,然后元素按变大的视口排列,然后再把视口缩放成屏幕实际宽度,这样就达到了缩小的效果。
小技巧:可以通过window.οnresize=()=>{}监测到PC端视口变化
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Documenttitle>
<style>
img {
width: 200px;
height: 150px;
}
style>
head>
<body>
<img src="../imgs/1.jpg">
<img src="../imgs/2.jpg">
<img src="../imgs/3.jpg">
<img src="../imgs/4.jpg">
<script>
console.log('当前浏览器视口的宽度为: ', document.documentElement.clientWidth);
script>
body>
html>
放大时:
缩小时:
注意:移动端缩放不会影响页面布局,因为缩放的时候,布局视口大小没有变化,简单记住:移动端的缩放没有改变布局视口的任何东西。而pc端缩放的时候,视口(pc端就一种视口)会变化,导致页面布局会产生变化。
形象理解:拿一个中间镂空的的纸片(镂空部分就相当于屏幕),挡在眼睛前面,去看前面的内容,当纸片离前面的内容越近看到的东西就越少,而镂空部分的大小又是不变的,因此看到的东西就会变大,类似于放大;缩小也就是镂空纸片离前面的内容越远
meta-viewport标签是苹果公司在2007年引进的,用于移动端布局视口的控制,企图改变980布局视口的行业规则。
width值可以是device-width(让布局视口的宽度等于设备独立像素值),也可以是具体值,但有些安卓手机不支持具体值,IOS全系列支持
DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width">
<title>Documenttitle>
head>
<body>
body>
<script>
console.log('布局视口宽度为: ' + document.documentElement.clientWidth);
script>
html>
是否允许用户通过手指缩放页面 【safari不支持】
设置为cover可以解决【刘海屏】的留白问题
移动端如下设置viewport:开启理想视口,禁止缩放
"viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
由于移动端设备的屏幕尺寸大小不一,会出现:同一个元素,在两个不同的手机上显示效果不一样(比例不同)。要想让同一个元素在不同设备上,显示效果一样,就需要适配,无论采用何种适配方式,中心原则永远是:等比!
主流的适配方式有三种:
比如有一个设计稿是,可以看到是在iponhe6(设备独立像素宽度为375px)的条件下设计的
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
* {
margin: 0;
}
.demo {
width: 345px;
height: 150px;
margin: 0 auto;
margin-top: 15px;
background-color: #a2bbee;
}
style>
head>
<body>
<div class="demo">div>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=375">
<title>viewport适配title>
<style>
* {
margin: 0;
padding: 0;
}
.demo {
width: 345px;
height: 150px;
margin: 0 auto;
margin-top: 15px;
background-color: #a2bbee;
border: 1px solid #000;
}
style>
head>
<body>
<div class="demo">div>
body>
html>
em 和 rem 都是 css 中的长度单位。而且两个都是相对长度单位,不过两个有点区别
rem适配的原理:编写样式时统一使用rem为单位,在不同设备上动态调整根字体大小
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>em和remtitle>
<style>
* {
margin: 0;
padding: 0;
}
html,body {
/* 设置根元素字体大小 */
font-size: 30px;
}
.test1 {
width: 400px;
height: 400px;
background-color: pink;
}
.test2 {
width: 10em;
height: 10rem;
/* 设置当前元素的字体的大小 */
font-size: 20px;
background-color: #bfa;
}
style>
head>
<body>
<div class="test1">
<div class="test2">div>
div>
body>
html>
淘宝、百度的移动端页面用的此方案
理想视口下
(注意:此方案需要先设置理想视口),以设计稿(dip为375px)为标准,根字体设计为100px,来匹配其它设备的dip
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Documenttitle>
<style>
* {
margin: 0;
padding: 0;
}
#demo {
/* (未适配前的书写的代码)
width: 345px;
height: 150px;
margin: 0 auto;
margin-top: 15px;
background-color: #a2bbee; */
/* 第二步:换算成rem */
width: 3.45rem;
height: 1.5rem;
margin: 0 auto;
margin-top: 0.15rem;
background-color: #a2bbee;
/* 对于不需要适配的情况,就不要使用rem了,而是使用px */
border: 1px solid black;
}
style>
head>
<body>
<div id="demo">div>
body>
<script>
function adapter() {
// 获取布局视口宽度,因为开启了理想视口(因此第一步就需要开启理想视口),就会有这个等式关系:布局视口=设备横向独立像素值
const dpWidth = document.documentElement.clientWidth // 因此这里拿到布局视口的宽度就是设备横向独立像素值
// 计算根字体大小(这是根据比例关系计算而来)
const rootFontsize = (dpWidth * 100)/375
// 设置根字体大小
document.documentElement.style.fontSize = rootFontsize + 'px'
}
adapter()
// 监听布局视口的变化(当通过浏览器控制台切换不同机型时,实时的适配)
window.onresize = adapter
script>
html>
理想视口下,根字体设为dip/10,即把dip比作10份rem,考虑内部元素的占多少rem
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Documenttitle>
<style>
* {
margin: 0;
padding: 0;
}
#demo {
/* (未适配前的书写的代码)
width: 345px;
height: 150px;
margin: 0 auto;
margin-top: 15px;
background-color: #a2bbee; */
/* 第二步:换算成rem */
width: 9.2rem;
height: 4rem;
margin: 0 auto;
margin-top: 0.4rem;
background-color: #a2bbee;
/* 对于不需要适配的情况,就不要使用rem了,而是使用px */
border: 1px solid black;
}
style>
head>
<body>
<div id="demo">div>
body>
<script>
function adapter() {
// 获取布局视口宽度,因为开启了理想视口(因此第一步就需要开启理想视口),就会有这个等式关系:布局视口=设备横向独立像素值
const dpWidth = document.documentElement.clientWidth // 因此这里拿到布局视口的宽度就是设备横向独立像素值
// 计算根字体大小(这是根据比例关系计算而来)
const rootFontsize = dpWidth / 10
// 设置根字体大小
document.documentElement.style.fontSize = rootFontsize + 'px'
}
adapter()
window.onresize = adapter
script>
html>
* {
margin: 0;
padding: 0;
}
@font: (375/10rem);
#demo{
width: (345/@font);
height: (150/@font);
margin: 0 auto;
margin-top:(15/@font);
background-color: #a2bbee;
/* 对于不需要适配的情况,就不要使用rem了,而是使用px */
border: 1px solid black;
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Documenttitle>
<link rel="stylesheet" href="./demo.css">
head>
<body>
<div id="demo">div>
body>
<script>
function adapter() {
// 获取布局视口宽度,因为开启了理想视口(因此第一步就需要开启理想视口),就会有这个等式关系:布局视口=设备横向独立像素值
const dpWidth = document.documentElement.clientWidth // 因此这里拿到布局视口的宽度就是设备横向独立像素值
// 计算根字体大小(这是根据比例关系计算而来)
const rootFontsize = dpWidth / 10
// 设置根字体大小
document.documentElement.style.fontSize = rootFontsize + 'px'
}
adapter()
window.onresize = adapter
script>
html>
上面的示例是按照375,即iphone6作为样板设计的。如果设计稿不是375,则按照上面的方法(看上面图中的核心过程),按比例计算即可(需要适配的尺寸按上面的方法计算,js代码只需要改动对应的地方的尺寸即可)。
vw和vh是两个相对单位
不过vw和vh有一定的兼容性问题:详见:这里
所以我们可以代码大概可以怎么写?
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
* {
margin: 0;
padding: 0;
}
#demo {
background-color: hotpink;
/* width: 345px;
height: 150px;
margin: 15px; */
/* 对于需要适配的尺寸,就看这个设计尺寸占宽度的百分比 */
/* 345/375 *100 = 92 */
width: 92vw;
/* 150/375 *100 = 40 */
height: 40vw;
/* 15/375 *100 = 4 */
margin: 4vw;
margin-bottom: 0;
/* 对于不需要适配的尺寸,直接写px单位 */
border: 1px solid black;
}
style>
head>
<body>
<div id="demo">div>
body>
html>
@vwSize: 375/100vw;
* {
margin: 0;
padding: 0;
}
#demo {
background-color: hotpink;
/* width: 345px;
height: 150px;
margin: 15px; */
width:(345/@vwSize);
height: (150/@vwSize);
margin: (15/@vwSize);
margin-bottom: 0;
border: 1px solid black;
}
DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<link rel="stylesheet" href="./demo.css">
head>
<body>
<div id="demo">div>
body>
html>
在dpr为2或者3以上的情况下,1css像素对应2个或者3个物理像素(说通俗点就是高dpr下,1px的css像素所显示的效果并没是我们想象的1px效果)
默认情况下的1pxcss像素的显示效果
放大后的1px css像素的显示效果,可以明显看到边框肯定不是1px
设置物理像素边框适配后的效果,可以看到,即使在搞dpr下,边框也依旧为1px
DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
#demo {
width: 150px;
height: 150px;
/* background-color: hotpink; */
}
/* 关键代码就是媒体查询
dpr为2的情况下,就将border从1px设置为0.5px
这样子0.5px的css像素 只能点亮1px物理像素(0.5*2) */
@media screen and (-webkit-min-device-pixel-ratio: 2) {
#demo {
border: 0.5px solid black;
}
}
/* dpr为3的情况下,就将border从1px设置为0.33px
这样子0.33px的css像素 只能点亮1px物理像素(0.33*3) */
@media screen and (-webkit-min-device-pixel-ratio: 3) {
#demo {
border: 0.33px solid black;
}
}
style>
head>
<body>
<div id="demo">div>
body>
html>
移动端事件列表
以上事件最早出现于IOS safari中,为了向开发人员转达一些特殊的信息
注意:
DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
* {
margin: 0;
padding: 0;
}
#demo {
width: 100%;
height: 350px;
background-color: hotpink;
}
style>
head>
<body>
<div id="demo">div>
body>
<script>
let demo = document.querySelector('#demo')
demo.addEventListener('touchstart',()=>{
console.log('你手指触摸到粉色的盒子-touchstart');
})
demo.addEventListener('touchmove',()=>{
console.log('你手指在粉色的盒子上移动了-touchmove');
})
demo.addEventListener('touchend',()=>{
console.log('你手指在粉色的盒子上移开了-touchend');
})
demo.addEventListener('touchcancel',()=>{
console.log('触摸被打断了-touchcancel');
})
script>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
* {
margin: 0;
padding: 0;
}
#demo {
width: 100%;
height: 350px;
background-color: hotpink;
}
style>
head>
<body>
<div id="demo">div>
body>
<script>
/*
touches: 屏幕上的触点数(是个伪数组)
targetTouches: 当前元素上的触点数
changedTouches: 屏幕上改变了的触点数(也就是:同时按下几个手指)
*/
let demo = document.querySelector('#demo')
demo.addEventListener('touchstart',(e)=>{
// 阻止选择文字这一默认行为
e.preventDefault()
demo.innerHTML = '屏幕上的触点数: ' + e.touches.length + '
'
demo.innerHTML += 'demo盒子上的触点数: ' + e.targetTouches.length + '
'
demo.innerHTML += '屏幕上改变了的触点数: ' + e.targetTouches.length
})
script>
html>
touch事件结束后会默认触发元素的click事件
(同时给元素绑定click事件和touchstart事件,会先触发touchstart事件,然后过一个时间间隔,再触发click事件),如果没有设置完美视口,则事件触发的时间间隔为300ms左右,如设置完美视口则时间间隔为30ms左右(视具体设备特性而定)。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
.demo {
width: 100px;
height: 100px;
border: 1px solid black;
}
style>
head>
<body>
<div class="demo">demodiv>
body>
<script>
let demo = document.querySelector('.demo')
let time = null
demo.addEventListener('click',()=>{
let now = Date.now()
console.log('click事件发生了',now, now-time);
})
demo.addEventListener('touchstart',()=>{
time = Date.now();
console.log('touchStart事件发生了',time);
})
script>
html>
点击穿透条件
想更详细的可以看看这位博主写的:移动端点击穿透问题
也可以这样子说: 如果 touch 事件隐藏了元素,则 click 动作将作用到新的元素上,触发新元素的 click 事件或页面跳转,此现象称为点击穿透
触发蒙层的touchstart方法,蒙层消失,触发该元素位置下的click事件。
DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>点击穿透title>
<style>
* {
margin: 0;
padding: 0;
}
html,body {
height: 100%;
width: 100%;
}
#app {
height: 100%;
background-color: pink;
text-align: center;
position: relative;
}
.link {
display: block;
height: 200px;
background-color: #bfa;
}
.shade {
position: absolute;
width: 100%;
height: 100%;
top: 0;
background-color: rgba(0,0,0,.3);
}
.shade h1 {
margin-top: 80px;
margin-bottom: 20px;
}
#btn {
width: 150px;
height: 50px;
border: none;
}
style>
head>
<body>
<div id="app">
<a href="http://www.baidu.com" class="link">跳转到百度a>
<div class="shade">
<h1>恭喜一等奖h1>
<button id="btn">关闭button>
div>
div>
body>
<script>
let shade = document.querySelector('.shade')
let btn = document.querySelector('#btn')
btn.addEventListener('touchstart',()=>{
/* 点击关闭按钮,shade被隐藏,将会触发a标签的点击事件,然后跳转页面 */
shade.style.display = 'none'
})
/* 这个点击事件不会触发, 因为发生touchstart事件时, shade就被隐藏了, btn就没了。 */
btn.addEventListener('click',()=>{
console.log('点击。。。');
})
script>
html>
阻止默认行为
btn.addEventListener('touchend',(event)=>{
event.preventDefault()
shade.style.display = 'none'
})
让背后元素不具备click特性,修改为普通div标签:
<div id="baidu">点我去百度div>
利用touchend事件,点击跳转新网页
baidu.addEventListener('touchend',()=>{
window.location.href = 'https://www.baidu.com'
})
利用css中的pointer-events属性让背后的元素暂时失去click事件,300毫秒后再复原:
.link{
display: block;
width: 100%;
height: 300px;
background-color: skyblue;
pointer-events: none;
}
btn.addEventListener('touchend',()=>{
shade.style.display = 'none'
setTimeout(() => {
baidu.style.pointerEvents = 'auto' // 恢复正常
}, 300);
})
让隐藏的元素延迟300毫秒左右再隐藏
btn.addEventListener('touchend',()=>{
setTimeout(() => {
shade.style.display = 'none'
}, 300);
})