前端常见面试题(九)@郝晨光


请详解移动端点透,为什么会发生点透?描述发生的场景及解决方案

提到移动端点透问题,就不得不先提到移动端的click事件300ms延迟问题

一、移动端click事件300ms延迟问题

在移动端执行click事件时,通常移动端的浏览器会延迟300ms来触发对应的事件,这个问题的原因是:为了判断用户是否是双击,因为在移动端浏览器刚开始的时候,为了提升用户体验感,开发了双击缩放和双击滚动等默认行为,在之前的web开发中,体验并不明显,在当前运行速度和用户体验至上的时代,这个问题表现的特别严重。

移动端click事件300ms延迟解决方案
  1. 添加meta标签,阻止用户双击缩放,并限制视口宽度
    <meta
       name="viewport" 
       content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
     />
    
  2. 设置CSStouch-action
    CSS属性 touch-action 用于指定某个给定的区域是否允许用户操作,以及如何响应用户操作(比如浏览器自带的划动、缩放等)。
    * {
      touch-action: none;
    }
    
  3. fastclick.js
    fastclick.js- github网址
    移动端事件触发顺序:在移动端,手指点击一个元素,会经过:touchstart => touchmove => touchend => click
    fastclick.js的原理是:FastClick的实现原理是在检测到touchend事件的时候,会通过DOM自定义事件立即触发模拟一个click事件,并把浏览器在300ms之后真正的click事件阻止掉。
    在原生js中可以如下使用
    if ('addEventListener' in document) {
        document.addEventListener('DOMContentLoaded', function() {
            FastClick.attach(document.body);
        }, false);
    }
    // 文章由 郝晨光 整理,未经同意禁止转载
    
    在jquery或zpeto中可以如下使用
    $(function() {
        FastClick.attach(document.body);
    });
    
    在cli工具中(require或者import)
    const FastClick = require('fastclick');
    // import FastClick from 'fastclick';
    FastClick.attach(document.body, options);
    

二、移动端点透问题

点透问题出现的场景

当A/B两个层上下z轴重叠,上层的A点击后消失或移开(这一点很重要),并且B元素本身有默认click事件(如a标签)或绑定了click事件。在这种情况下,点击A/B重叠的部分,就会出现点透的现象。

总结如下:

  1. A/B两个层上下z轴重叠(上下重叠,A盖着B)。
  2. 上层的A点击后消失或移开。(这一点很重要)
  3. B元素本身有默认click事件(如a标签) 或 B绑定了click事件。
点透问题的出现原因

点透问题出现的原因就是因为我们上边说过的移动端click事件300ms延迟问题,当点击上层元素时,先触发touchstart事件,然后在300ms后会触发click事件,而此时上层元素已经消失,所以下边的元素会触发click事件,这就是点透

点透问题的解决方案
  1. fastclick.js
    fastclick.js既然可以解决click300ms延迟,那必然可以解决点透问题,使用方法如上文所述。

  2. 对于B元素本身存在默认click事件的情况,使用touchend代替touchstart事件并阻止掉时A元素touchend的默认行为preventDefault(),因为触发touchend需要200ms,从而阻止click事件的产生。

  3. 使用一个(透明)遮罩层,屏蔽所有事件,然后400ms(对于IOS来说是个理想值)后自动隐藏

  4. 延迟一定的时间(300ms+)来处理事件

  5. 直接使用click事件,不考虑延迟问题

  6. 下层避开click事件,如a链接改为span等标签,使用js跳转页面



移动端为什么会有一像素问题?如何解决?

为什么会有一像素问题?

因为在移动端,由于屏幕分辨率的不同,现在分为一倍屏、二倍屏、三倍屏。在不同的分辨率上,有可能一像素被渲然成二个像素点或者三个像素点,所以在实际写代码的时候,我们写的 border: 1px solid #000; 可能实际被渲然为 2px/3px;

一像素问题的解决方案

  1. 先使用伪类元素实现边框效果,然后通过媒体查询来操控transform: scale来适配不同分辨率
    .border-bottom{
        position: relative;
    }
    .border-bottom::after {
        content: " ";
        position: absolute;
        left: 0;
        bottom: 0;
        width: 100%;
        height: 1px;
        background-color: #e4e4e4;
        -webkit-transform-origin: left bottom;
        transform-origin: left bottom;
    }
    
    /* 2倍屏 */
    @media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
        .border-bottom::after {
            -webkit-transform: scaleY(0.5);
            transform: scaleY(0.5);
        }
    }
    
    /* 3倍屏 */
    @media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
        .border-bottom::after {
            -webkit-transform: scaleY(0.33);
            transform: scaleY(0.33);
        }
    }
    
  2. 使用border-image来代替border
    .border-image-1px {
        border-width: 1px 0px;
        -webkit-border-image: url("border.png") 2 0 stretch;
        border-image: url("border.png") 2 0 stretch;
    }
    
  3. 使用viewport +rem
    设置meta标签
    <meta
         name="viewport"
         id="WebViewport"
         content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    /> 
    
    并在js中通过判断当前是一倍屏还是二倍屏、三倍屏,来动态的设置meta标签的内容
    function rem() {
        document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
        let viewport = document.querySelector("#WebViewport")
        if (window.devicePixelRatio == 1) {
            viewport.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no')
        } 
        if (window.devicePixelRatio == 2) {
            viewport.setAttribute('content', 'width=device-width, initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no')
        } 
        if (window.devicePixelRatio == 3) {
            viewport.setAttribute('content', 'width=device-width, initial-scale=0.333333333, maximum-scale=0.333333333, minimum-scale=0.333333333, user-scalable=no')
        } 
    }
    rem()
    window.onresize = rem;
    // 文章由 郝晨光 整理,未经同意禁止转载
    
  4. border.css
    通过项目中引入border.css来解决



你还知不知道其他移动端的常见问题?

  1. html5调用安卓或者ios的拨号功能
    html5提供了自动调用拨号的标签,只要在a标签的href中添加tel:就可以了。

     <a href="tel:10086">点击拨打10086</a>
    
  2. IOS设备链接、按钮等点击产生灰色背景

    -webkit-tab-highlight-color:rgba(0,0,0,0);
    //去掉背景高亮
    
    -webkit-tab-highlight-color: red;
    //设置背景高亮的颜色
    
  3. ios设备微信浏览器或者Safari中fixed定位的部分会跟随滑动跳动
    在移动端始终使用absloute来模拟fixed绝对定位,而不使用fixed

  4. 移动端HTML5 audio autoplay失效问题
    由于自动播放网页中的音频或视频会给用户带来困扰或不必要的流量消耗,所以苹果系统和安卓系统通常都会禁止自动播放和使用JS的触发播放,必须由用户来触发才播放;解决方法思路:先通过用户touchstart触碰触发播放并暂停(让音频开始加载),后面用JS再操作就没问题了;解决代码:

    document.addEventListener('touchstart', function () {
        document.getElementsByTagName('audio')[0].play();
        document.getElementsByTagName('audio')[0].pause();
    });
    
  5. CSS动画页面闪白,动画卡顿,图片错乱的问题
    1.尽可能地使用合成属性transform和opacity来设计CSS3动画,不使用position的left和top来定位;
    2.开启硬件加速;

    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0); //可以触发硬件加速,从而让浏览器在渲染动画时从CPU转向GPU 
    
  6. 长按页面元素被选中
    使用css属性user-select

    -webkit-user-select:none; // webkit浏览器  
    -khtml-user-select:none; // 早期浏览器 
    -moz-user-select:none; // 火狐 
    -ms-user-select:none; // IE10 
    user-select:none; 
    
  7. 顶部状态栏背景色

    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    

    除非你先使用apple-mobile-web-app-capable指定全屏模式,否则这个meta标签不会起任何作用;
    如果content设置为default,则状态栏正常显示;
    如果设置为blank,则状态栏会有一个黑色的背景;
    如果设置为blank-translucent,则状态栏显示为黑色半透明;
    如果设置为default或blank,则页面显示在状态栏的下方,即状态栏占据上方部分;页面占据下方部分,二者没有遮挡对方或被遮挡;
    如果设置为blank-translucent,则页面会充满屏幕,其中页面顶部会被状态栏遮盖住(会覆盖页面20px高度,而iphone4和itouch4的Retina屏幕为40px);



如果本文对您有帮助,可以看看本人的其他文章:
前端常见面试题(八)@郝晨光
前端常见面试题(七)@郝晨光
前端常见面试题(六)@郝晨光

友情链接:Vue-cli3.0二次封装axios @于志程

本文 CSDN 地址: 前端常见面试题(九)@郝晨光

结言
感谢您的查阅,本文由郝晨光整理并总结,代码冗余或者有错误的地方望不吝赐教;菜鸟一枚,请多关照
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • # 移动端开发 ### 1. 1px问题如何解决 #### ①伪类 + transform(比较完美) > 原理是...
    sunnyRube阅读 860评论 0 0
  • meta基础知识 H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 忽略将页面中的数字识别为电话号码 忽略And...
    Mycro阅读 586评论 0 2
  • 请参看我github中的wiki,不定期更新。https://github.com/ivonzhang/Front...
    zhangivon阅读 7,103评论 2 19
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,421评论 1 45
  • 一日之计在于晨, 一年之计在于春… 日曰复明日,明日何其多?。 山東,青島。
    春風化雨阅读 201评论 0 0