web移动端问题摘要

web移动端问题摘要

移动端web遇到的问题摘要,记录在这里,持续更新….

针对有些手机不支持text-decoration的现象

    通过添加border-bottom的方式去模拟,安卓手机市场采用的标准太乱了,希望越来越符合w3c的标准吧。

微信分享完后页面会出现白屏的现象

    在一些安卓手机下在做微信分享时,分享完后页面会出现白屏的现象.
在分享api的回调里面去执行window.reload(),这样势必会造成多余的请求,在微信官方论坛一直没发现此类问题的解决方法,jsdk能越来越优化吧。

footer始终固定在底部

    在做h5页的时候,经常底部是存在公司logo的,页面内容高度能撑满一屏时没问题,而随页面内容的增加而填充在主体内容的下方,这样绝对定位有问题;解决方法是:不满时用绝对定位且父元素要预留footer的高度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
<head>
<style type="text/css”>
html,body{height:100%}
.footer {margin-top:-30px;
height:30px;
background-color:#eee;
}
.wrap{min-height:100%}
.main{padding-bottom:30px;
overflow:hidden;
}
</style>
</head>
<body>
<div class="wrap”>
<div class="main">这里是网页的主体</div>
</div>
<div class="footer">这里是页脚</div>
</body>
</html>

a标签中使用img后的高度多了几个像素

    a元素下有一个匿名文本,这个文本外有一个匿名行级盒子,它有的默认vertical-align是baseline的,而且往往因为上文line-height的影响,使它有个line-height,从而使其有了高度,因为baseline对齐的原因,这个匿名盒子就会下沉,往下撑开一些距离,所以把a撑高了。
    解决办法:
1.设置a的line-height:0或者font-size:0(如何内存在字体该方法不可用);
2.img设置display:block 同时移动端图片适配压缩的话,设置img的width:100%;

display:inline-block之间会存在间隙

    经常在把a标签变成一个button时会设置这个属性,移动端多个button并排时,如何做到自适应呢,外层div设置宽度100%和text-align:center,这也是水平居中元素的方法,内层a标签设置宽度百分比,相互之间的间距,设置左边a的margin-left百分比,注意计算,整体不要超过100%;那么不用这种方法来设置会产生间隙,解决方法:html代码不要换行;font-size:0;margin负边距,letter-spacing和word-spacing;inline-block并且元素高度不一致时,设置vertical-align为相同值使其垂直方向位置一致

图片加载完成判断 ,计算坐标 手机端自适应

1
2
3
4
5
6
$(window).load(function(){
var img=$(‘.inside_bgp');//整页是以一张图片作为背景
var theImg=new Image();
theImg.src=img.attr(’src’);
var bi=img.height()/theImage.height;//比率
})

获取页面模版时的处理

    获取模版html既修改其中的某个id的值后append,注意获取模版时就要获取其对象,不要获取后再变为对象($)。类似改变值类型的值,应该改变其引用类型

移动端上传图片压缩功能实现

    手机上经常会用到上传图片的功能,随着智能手机的像素越来越高,基本上照出来的图片都在3M以上,这边遇到的一个情况是,服务端接口限制了图片大小为2M,这种接口一般都是通用的,让后端改接口大小限制肯定是不可能的啦,所以这边针对用户上传图片到服务端之前做一个压缩处理,具体实现是通过canva绘制等比图片转换为base64:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var reader = new FileReader();
var $img = new Image();
reader.readAsDataURL(file);
reader.onload=function(e){
$img.src = this.result;
}
$img.onload = function() {
var width = $img.width,
height = $img.height,
scale = width / height;
width = parseInt(800);
height = parseInt(width / scale);
var $canvas = $('<canvas>');
if (!$canvas[0] || !$canvas[0].getContext) {
alert('版本太低,请升级软件');
return false;
}
var ctx = $canvas[0].getContext('2d');
$canvas.attr({width : width, height : height});
ctx.drawImage($img, 0, 0, width, height);
base64 = $canvas[0].toDataURL('image/jpeg',1);
base64 = base64.substr(22);
}

生成base64后form提交或者ajax提交就行了。

border 1像素渲染问题及flexible.js针对我司app做的更改

    目前我司移动端适配采用了手淘的flexible.js这个库,来动态生成meta标签、font-size、dpr,但在我司app webview里面写border:1px solid #ccc 渲染会出现错乱问题,特别是针对分页加载商品流的时候,这里采用了其它方案来写border,比如说用box-shadow

1
box-shadow:0 0 0 1px #ccc inset;

    由于手淘这个库是动态生成scale的,在我司的iphone6 app内还存在scale问题,导致出现页面出现一点点轻微滚动条,这进一步导致app原生回退方法调不起来的问题,这里我们也做了异常处理

1
2
3
if (scale == 0.5 && isIPhone && window.screen.width == 375) {
scale = 0.52;
}

    还有几时针对目前市面上安卓的屏幕分辨率过多,我们这边针对安卓的,所有的dpr都设置为1,还有像那种页面投放到其它渠道即其它安卓app的webview,都设置为1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (dpr >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (dpr >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}

    技术是为解决业务而生,适合自己业务的才是好的解决方案~~

touch事件

    touches:当前屏幕上所有触摸点的集合列表
    targetTouches: 绑定事件的那个结点上的触摸点的集合列表
    changedTouches: 触发事件时改变的触摸点的集合
    比如:div1, div2只有div2绑定了touchstart事件,第一次放下一个手指在div2上,触发了touchstart事件,这个时候,三个集合的内容是一样的,都包含这个手指的touch,然后,再放下两个手指一个在div1上,一个在div2上,这个时候又会触发事件,但changedTouches里面只包含第二个第三个手指的信息,因为第一个没有发生变化,而targetTouches包含的是在第一个手指和第三个在div2上的手指集合,touches包含屏幕上所有手指的信息,也就是三个手指。

关于localStorage、sessionStorage的问题

    移动端本地存储,当遇到浏览器开启隐私模式或无痕浏览时,存在其对象,但是它们的方法是实效的,会报错:QuotaExceededError,所以在用的时候,需要做异常处理try{}catch{},还是有就是在刷新本地缓存的时机上,比如像Safari回退时不会重新加载页面(非spa),这里可能需要用到popstate事件来监测用户回退。

事件代理不上,针对非a标签的解决方法

    There is an issue with iOS not registering click/touch events bound to elements added after DOM loads.I’ve found this the easy fix, simply add this to the css: cursor: pointer;

移动端点透处理

   点透问题 zepto的tap通过兼听绑定在document上的touch事件来完成tap事件的模拟的,及tap事件是冒泡到document上触发的,再点击完成时的tap事件(touchstart\touchend)需要冒泡到document上才会触发,而在冒泡到document之前,用户手的接触屏幕(touchstart)和离开屏幕(touchend)是会触发click事件的,因为click事件有延迟触发(这就是为什么移动端不用click而用tap的原因)(大概是300ms,为了实现safari的双击事件的设计)

判断js是否加载完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var s=document.getElementsByTagName('head')[0],url='/resources/mgc/js/vendor.eba7e7bf.js'
var b=document.createElement('script');
b.setAttribute('type','text/javascript');
b.setAttribute('src',url);s.appendChild(b);
b.onload=function(){
console.log('ok!');
}
//ie8
b.onreadystatechange=function(){
if(b.readyState=='loaded'||b.readyState=='complete'){
console.log('dd');
}
}

es6 Array新方法

1
of、from、includes、find、findIndex、copyWithin、keys、values、entries、fill

js监听对象属性变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//回调函数
function $watch(obj, prop, callback) {
if (!obj.$property) {
obj.$property = function(prop, value) {
if (this[prop] != value) {
this[prop] = value;
return callback(this);
}
return this;
}
}
}
$watch(obj,'a',function(obj){
console.log("obj的属性a的发生改变:"+obj.a);
});
//defineProperty vue原理
Object.defineProperty(obj,"a",{
set:function(val){
console.log("obj的属性a的发生改变:"+val);
}
get:function() {
console.log(this.a);
}
})
坚持技术分享,您的支持将鼓励我继续创作!