移动端制作遇到的各种问题

论坛 期权论坛 脚本     
匿名技术用户   2020-12-29 18:32   320   0
.点击的穿透问题
做过移动端可能都遇到这个问题,网上也有很多解决方案,但是大多数对于性能或是用户体验不是特别完美,下面我来简单说一说吧.
1.不要混用touch和click
    既然touch之后300ms会触发click,只用touch或者只用click就自然不会存在问题了
2.吃掉(或者说是消费掉)touch之后的click
    依旧用tap,只是在可能发生点击穿透的情形做额外的处理,拿个东西来挡住、或者tap后延迟350毫秒再隐藏mask、pointer-events、在下面元素的事件处理器里做检测(配合全局flag)等等,能吃掉就行
1.只用touch
    最简单的解决方案,完美解决点击穿透问题.
    把页面内所有click全部换成touch事件(touchstart、’touchend’、’tap’),需要特别注意a标签,a标签的href也是click,需要去掉换成js控制的跳转,或者直接改成span + tap控制跳转。如果要求不高,不在乎滑走或者滑进来触发事件的话,span + touchend就可以了,毕竟tap需要引入第三方库.
    不用a标签其实没什么,移动app开发不用考虑SEO,即便用了a标签,一般也会去掉所有默认样式,不如直接用span
2.只用click
    下下策,因为会带来300ms延迟,页面内任何一个自定义交互都将增加300毫秒延迟,想想都慢
    不用touch就不会存在touch之后300ms触发click的问题,如果交互性要求不高可以这么做,强烈不推荐,快一点总是好的
3.tap后延迟350ms再隐藏mask
    改动最小,缺点是隐藏mask变慢了,350ms还是能感觉到慢的
    只需要针对mask做处理就行,改动非常小,如果要求不高的话,用这个比较省力
4.pointer-events
    比较麻烦且有缺陷,不建议使用
    mask隐藏后,给按钮下面元素添上pointer-events: none;样式,让click穿过去,350ms后去掉这个样式,恢复响应
    缺陷是mask消失后的的350ms内,用户可以看到按钮下面的元素点着没反应,如果用户手速很快的话一定会发现

2.屏幕自适应的问题(rem的转换计算)
    设计稿是基于6plus设计的,屏幕宽度是414px

    1.基于jQuery实现的
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(function(){
    var num = $(window).width();
    var font = num/10;
    $("html").css("font-size",font+"px");
    window.onresize=function(){
        num = $(window).width();
        font = num/10;
        $("html").css("font-size",font+"px");
    }
    //cssrem
    console.log($("#css").html().replace(/(\d+(.\d+)*)px/g,function($0,$1){
        return ($1/41.4+"").substring(0,8)+"rem"
    }));
})

    2.基于原生js实现的
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>  
!function(n) {
    var e = n.document,
    t = e.documentElement,
    i = 720,
    d = i / 100,
    o = "orientationchange" in n ? "orientationchange": "resize",
    a = function() {
        var n = t.clientWidth || 320;
        n > 720 && (n = 720),
        t.style.fontSize = n / d + "px"
    };
    e.addEventListener && (n.addEventListener(o, a, !1), e.addEventListener("DOMContentLoaded", a, !1))
} (window);


3.布局问题
    圣杯布局和双飞翼布局,他们的都要求三列布局,中间宽度自适应,两边定宽,这样做的优势是重要的东西放在文档流前面可以优先渲染,而双飞翼布局是对圣杯布局的一种改良.
    1.  圣杯布局
        利用float来实现,首先将三列放到一个父元素内后左浮动,之后给左右中分别设置宽度200px,250px,100%。之后给中间,右边分别设置margin-left为-200px,-250px。之后再将左右两列进行相对定位position:relative;并分别设置left:-200px;right:-250px;最后便是等高布局了,给左中右设置padding-bottom:2000px;margin-bottom:-2000px;给其父元素设置overflow:hidden即可。
        如下图所示:
              移动端制作遇到的各种问题(后续将继续总结...)
        
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
            padding-bottom2000px;
            margin-bottom-2000px;
        }
        .left{
            width200px;
            positionrelative;
            left-200px;
            background#0000cc;
        }
        .content{
            width100%;
            margin-left-200px;
            background#009900;
        }
        .right{
            width250px;
            positionrelative;
            right-250px;
            margin-left-250px;
            background#f0ad4e;
        }
    </style>
</head>
<body>
<div class="main">
    <div class="left">leftleftleftleftleftleft</div>
    <div class="content">mainmainmainmainmainmainmain<br /><br /><br />ddddddddd</div>
    <div class="right">riightrightrightrightright</div>
</div>
</body>
</html>


         利用绝对定位实现,首先左右实现绝对定位,分别设置left:0与right:0,宽度分别设置为200px与250px。中间元素设置为margin-left:200px;margin-right:250px。最后便是等高布局了,给左中右设置padding-bottom:2000px;margin-bottom:-2000px;给其父元素设置overflow:hidden和position:relative即可。
         如下图所示:
         移动端制作遇到的各种问题(后续将继续总结...)
         
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
        }
        .left,.right{
            positionabsolute;
        }
        .left{
            width200px;
            left0;
            top0;
            background#1da1f2;
        }
        .content{
            margin-left200px;
            margin-right250px;
            background#ffff4f;
        }
        .right{
            width250px;
            right0;
            top0;
            background#009900;
        }
    </style>
</head>
<body>
<div class="main">
    <div class="left">leftleft</div>
    <div class="content">content<br /><br /><br />ddddddddd</div>
    <div class="right">right</div>
</div>
</body>
</html>


    2 . 双飞翼布局
        用float来实现,首先将左中右分别设置宽度为200px,100%,250px。中右分别设置margin-left为-200px和-250px.中间元素下有一个子元素,设置margin-left和margin-right分别为200px余250px。最后便是等高布局了,给左中右设置padding-bottom:2000px;margin-bottom:-2000px;给其父元素设置overflow:hidden即可。
        如下图所示:
            移动端制作遇到的各种问题(后续将继续总结...)
            
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
        }
        .left{
            width:200px;
            background#000;
        }
        .content{
            width100%;
            margin-left-200px;
        }
        .con{
            margin-left200px;
            margin-right250px;
            background#009900;
        }
        .right{
            width250px;
            margin-left-250px;
            background#0000cc;
        }
    </style>
</head>
<body>
    <div class="main">
        <div class="left">leftleft</div>
        <div class="content">
            <div class="con">conconconffffffffff<br /><br /><br />ddddddddd</div>
        </div>
        <div class="right">rightright</div>
    </div>
</body>
</html>

        圣杯布局与双飞翼布局的实现思路差异在哪里?
            圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏全部float浮动,但左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。
            不同在于解决”中间栏div内容不被遮挡“问题的思路不一样:
                 圣杯布局,为了中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。
                 双飞翼布局,为了中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置。
                 多了1个div,少用大致4个css属性(圣杯布局中间divpadding-left和padding-right这2个属性,加上左右两个div用相对布局position: relative及对应的right和left共4个属性,一共6个;而双飞翼布局子div里用margin-left和margin-right共2个属性,6-2=4),个人感觉比圣杯布局思路更直接和简洁一点。


4.border-radius问题
border-radius设置为奇数时,在pc上是圆的,在手机上是不圆的,所以在制作的时候,将border-radius制作成偶数值。
1
2
3
4
5
6
7
8
9
//
width:8px;
height:8px;
border-radius:50%;
//
width:9px;
height:9px;
border-radius:50%;


5.IOS中input与fixed同时存在的情况会出现bug
    两种解决方案,一种是将内容区域放在中间部分,只是中间部分在滚动(还是固定在底部);另一种是判断当是ios时,将其转换为absolute定位。(跟随着页面的滚动而滚动)
    到底选择那种解决方案,这就得和客户来商讨了,但是中间还是会出现一些问题:

第一种解决方案:
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    <footer>
        <input type="text" placeholder="Footer..."/>
        <button class="submit"></button>
    </footer>
</body>
header, footer, main {
    display: block;
}
header {
    position: fixed;
    height: 50px;
    left: 0;
    right: 0;
    top: 0;
}
footer {
    position: fixed;
    height: 34px;
    left: 0;
    right: 0;
    bottom: 0;
}
main {
    margin-top: 50px;
    margin-bottom: 34px;
    height: 2000px
}

    当使用input时,fixed定位的元素就会出现错位。软键盘唤起后,页面的 fixed 元素将失效(即无法浮动,也可以理解为变成了 absolute 定位),所以当页面超过一屏且滚动时,失效的 fixed 元素就会跟随滚动了。
    既然在 iOS 下由于软键盘唤出后,页面 fixed 元素会失效,导致跟随页面一起滚动,那么假如——页面不会过长出现滚动,那么即便 fixed 元素失效,也无法跟随页面滚动,也就不会出现上面的问题了。
    那么按照这个思路,如果使 fixed 元素的父级不出现滚动,而将原 body 滚动的区域域移到 main 内部,而 header 和 footer 的样式不变,代码如下:
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
header {
    position: fixed;//absolute
    height: 50px;
    left: 0;
    right: 0;
    top: 0;
}
footer {
    position: fixed;//absolute
    height: 34px;
    left: 0;
    right: 0;
    bottom: 0;
}
main {
/* main */
position: absolute;
top: 50px;
bottom: 34px;
/* 使 */
 overflow-y: scroll;
  /*  */
  -webkit-overflow-scrolling: touch;   
}
main .content {
    height: 2000px;
}


1
2
3
$("input").on("focus",function(){
   this.scrollIntoView();//androidinput
})


第二种解决方案:
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(function(){
    var browser = {
            versions: function () {
            var u = navigator.userAgent, app = navigator.appVersion;
            return { // 
            ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios 
            android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //androiduc 
            iPhone: u.indexOf('iPhone') > -1, //iPhoneQQHD 
            iPad: u.indexOf('iPad') > -1, //iPad 
            };
            }(),
            }
            if (browser.versions.iPhone || browser.versions.iPad || browser.versions.ios) {
                  //fixed
            }
    
    
}) 


6.移动端背景无法固定
在移动端制作固定背景时(利用fixed)会出现滚动条滚动时,背景图会跟着滚动,下面的方案可以解决这个问题:
1
2
3
4
5
6
7
8
9
10
11
body:before {
  content' ';
  positionfixed;
  z-index-1;
  top0;
  right0;
  bottom0;
  left0;
  backgroundurl(...) center 0 no-repeat;
  background-sizecover;
}


7.单行,多行文字显示...
单行显示省略号:
   
1
2
3
text-overflow:ellipsis;
white-space:nowrap;
overflow:hidden;

多行显示省略号:
    在WebKit浏览器或移动端(绝大部分是WebKit内核的浏览器)的页面实现比较简单,可以直接使用WebKit的CSS扩展属性(WebKit是私有属性)-webkit-line-clamp ;注意:这是一个 不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。
    -webkit-line-clamp用来限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他的WebKit属性。常见结合属性:
    display: -webkit-box; 必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。
    -webkit-box-orient 必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 。
    text-overflow: ellipsis;,可以用来多行文本的情况下,用省略号“…”隐藏超出范围的文本。
    这个属性比较合适WebKit浏览器或移动端(绝大部分是WebKit内核的)浏览器
   
1
2
3
4
display-webkit-box;
-webkit-box-orientvertical;
-webkit-line-clamp3;        //便
overflowhidden;

跨浏览器兼容的方案:
    比较靠谱简单的做法就是设置相对定位的容器高度,用包含省略号(…)的元素模拟实现;
   
1
2
3
4
5
6
7
8
p{positionrelativeline-height20pxmax-height40px;overflowhidden;}
p::after{content"..."positionabsolutebottom0right0padding-left40px;
background: -webkit-linear-gradient(lefttransparent#fff 55%);
background: -o-linear-gradient(righttransparent#fff 55%);
background: -moz-linear-gradient(righttransparent#fff 55%);
background: linear-gradient(to righttransparent#fff 55%);
}

    将height设置为line-height的整数倍,防止超出的文字露出。
    给p::after添加渐变背景可避免文字只显示一半。

    由于ie6-7不显示content内容,所以要添加标签兼容ie6-7(如:<span>…<span/>);兼容ie8需要将::after替换成:after。

    原文:http://www.qdfuns.com/notes/18271/84585853e65af0bad864a4e30c9c5154.html

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP