前端小站


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 日程表

  • 站点地图

  • 公益404

article

发表于 2019-06-11 |

码农翻身小记

发表于 2019-06-11 | 分类于 读书笔记 |

移动端开发兼容性问题

发表于 2019-05-09 |

移动端开发会让你经常会和测试说这样一些话:“我已经测了的,怎么会是这个样子?”;“我的手机上是正常的呀!”;“会不会是缓存~”;“还有这种操作???”……

刚开始不如移动端开发,这个时候才发现设备的兼容性是多么让人头疼,下面会记录一些我遇到的问题。这篇文章会持续不定期更新

我讲的不会很细致,只会讲出我遇到的问题和解决的思路及少量代码

ios使用fixed蒙层输入框

你会惊奇的发现,如果你在有弹框的蒙层用了fixed这种常规操作,很棒~,简单实用。but!ios会出现输入框闪烁的无奈问题,也不用纠结哪个版本的ios了,反正你都得改~。具体我们该怎么解决这个问题呢?用absolute?真好,我们想到了一起。但是要知道absolute并不能锁定整个屏幕,所以我给body设置overflow:hidden,但是这会导致body自动到顶部。实在没想出完美解决这个bug的简单用css就可以的方法。所以我用了js控制。主要是使用了两个函数,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 我用的是vue
// 思路很简单 就是弹框弹起时获取scrollTop 和 屏幕的高度
// 然后 两者相加为背景高度使用margin-top的负高度上移scrollTop的高度,
// 最后overflow:hidden;
// 关闭弹框时恢复设置
hasMask() {
this.top = document.documentElement.scrollTop || document.body.scrollTop;
const mainDom = document.querySelector('.pig-main');
this.pageMinHeight = document.querySelector('#app').clientHeight;
mainDom.style.marginTop = -this.top + 'px';
mainDom.style.height = this.pageMinHeight + this.top - 1 + 'px';
mainDom.style.overflow = 'hidden';

},
noMask() {
const mainDom = document.querySelector('.pig-main');
mainDom.style.marginTop = 0;
mainDom.style.height = '';
mainDom.style.overflow = '';
document.documentElement.scrollTop = this.top;
document.body.scrollTop = this.top;

}

然而这种方式在ios下也有一个bug,ios的title处会动态的小幅度变化,导致蒙层可滑动并且下方会有小部分空白。此时我选择监听scroll事件,动态改变高度。(ps: 弹框关闭时建议移除scroll事件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
changeHeight() {
const mainDom = document.querySelector('.pig-main');
this.pageMinHeight = document.querySelector('#app').clientHeight;
mainDom.style.marginTop = -this.top + 'px';
mainDom.style.height = this.pageMinHeight + this.top - 1 + 'px';
mainDom.style.overflow = 'hidden';
},
hasMask() {
this.top = document.documentElement.scrollTop || document.body.scrollTop;
this.changeHeight();
window.addEventListener('scroll', this.changeHeight)
},
noMask() {
const mainDom = document.querySelector('.pig-main');
window.removeEventListener('scroll', this.changeHeight)
mainDom.style.marginTop = 0;
mainDom.style.height = '';
mainDom.style.overflow = '';
document.documentElement.scrollTop = this.top;
document.body.scrollTop = this.top;
},

这个bug目前算是解决了,代码写的不好还见谅,我也会努力向大家学习。大家有更好的方法也可以推荐给我。

目前ios12及以上版本input框换起软盘后收起,页面没有恢复

这个bug解决的思路很简单:首先,未恢复的页面在发生scroll事件时就会恢复;接下来就是解决何时发生滚动,我采用的是在blur时scrollTo;最开始如果我们scrollTo(0, 0),就会出现一个新的bug就是你每切换一个输入框都会往上弹一下,用户体验会很差;所以就在blur时计算此时的scrollTop值;然后加1px。:)最后因为ios切换输入框滚动有个延时,所以最后代码如下:

1
2
3
4
5
6
7
8
9
10
if (/os 12/ig.test(navigator.userAgent)) {
window.addEventListener('blur', () => {
let currentTop;
setTimeout(() => {
currentTop = document.documentElement.scrollTop || document.body.scrollTop;
currentTop += 1;
window.scrollTo(0,currentTop);
},300);
},true)
}
手机锁屏倒计时停止

手机锁屏的解决方案如果不是webview的页面,用网上的监听页面事件的解决方案是不好解决的,get到一个简单方法就是在setinterval里获取当前时间,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const timer = setInterval(function () {
timeleft = parseInt((finishTime - new Date().getTime()) / 1000) // 重复获取时间
min = Math.floor(timeleft / 60);
sec = Math.floor(timeleft % 60);

min = min < 10 ? "0" + min : min;
sec = sec < 10 ? "0" + sec : sec;
self.timeLeftShow = `${min}:${sec}`;
timeleft--;
if (timeleft <= 0) {
self.canPay = false;
clearInterval(timer);
}
}, 1000);

axios和ajax及fetch原理浅析

发表于 2019-05-08 | 分类于 学习笔记 |

这三个其实都是用来请求数据的,那他们的区别在哪里呢?其实 axios 和 ajax
都是对XMLHttpRequest这个对象的封装;而fetch则是window下的一个方法,是一个更底层的方法。


ajax

其实重点就是首先实例一个XMLHttpRequest对象,用其中的open方法建立连接;send方法传输数据(前端传到后台);然后再利用onreadystatechange 监听readyState的变化,当其为4时,代表请求完成;简单的代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const Ajax={
get: function(url, fn) {
// XMLHttpRequest对象用于在后台与服务器交换数据
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
// readyState 为4说明请求已完成
if (xhr.readyState == 4 && xhr.status == 200) {
// 从服务器获得数据
fn.call(this, xhr.responseText);
}
};
xhr.send();
},
// datat应为'a=a1&b=b1'这种字符串格式,在jq里如果data为对象会自动将对象转成这种字符串格式
post: function (url, data, fn) {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
// 添加http头,发送信息至服务器时内容编码类型
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status == 200)) {
fn.call(this, xhr.responseText);
}
};
xhr.send(data);
}
}

axios

axios其实就是在ajax的基础上加了promise,具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
const myAxios = {
get: function(url) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText)
}
};
xhr.send();
})
},

fetch

fetch的使用这里就不多做赘述,有很多这方面的文档。fetch首先不想ajax一样需要引入jq;如果想自己实现ajax呢,步骤相对于fetch来说也是相当的繁琐;同时fetch也加入了promise,解决了回调地狱的问题;使用fetch虽然简单,但是也有一些问题需要注意:

  • cookie传递
    必须在header参数里面加上credientials: ‘include’,才会如xhr一样将当前cookies带到请求中去
  • fetch和xhr的不同
    fetch虽然底层,但是还是缺少一些常用xhr有的方法,比如能够取消请求(abort)方法
    fetch在服务器返回4xx、5xx时是不会抛出错误的,这里需要手动通过,通过response中的ok字段和status字段来判断
wendell

wendell

以前我没得选,现在我选择当个程序员

4 日志
2 分类
3 标签
GitHub E-Mail
© 2019 wendell