时光不负,创作不停,本文正在参加2021年终总结征文大赛
总结了一些平时在开发H5的时候遇到的问题,和解决方案,还有一些自己用的比较多的js,如有不对的地方,请大佬们轻喷。如果jio的还可以的话,麻烦大佬们点个赞支持一下,蟹蟹!!!
1、修复点击无效问题
问题说明:在
iOS系统上有些情况下非可点击元素监听click事件可能会无效
解决方案:
- 换成
<button>或者<a>标签来绑定click事件 - 只需对不触发click事件的标签声明
css属性cursor: pointer
2、阻止默认滚动穿透
问题说明:在
iOS系统中,如果使用第三方滚动组件的话,就会出现系统自带滚动和组件同时发生滚动,这个时候就会导致上拉或者下拉出现白边。 解决方案:
document.body.addEventListener('touchmove', function(e) {
e.preventDefault();
}, {
passive: false // 是否让 阻止默认行为(preventDefault()) 失效
});
3、iOS/Android中的浏览器(H5)中唤起本地APP解决方案
问题说明:在APP未安装情况下,引导用户下载后打开APP后,如何进入之前唤起时指定的页面或内容。用户点击了页面的对应唤起APP的操作,页面就会无任何的交互,用户体验就有一些不友好。
解决方案:
- 设置比较小的运行间隔(< 30ms),在浏览器或者webview中,应用切换到后台,setInterval会被很明显的延迟执行,比如设置一个运行间隔20ms,总计运行100次的定时器,如果页面一直处于前台,则100次跑完,总耗时与100x20=2000ms不会有太大差异,但页面在后台运行时,此时间会明显超过2000ms。可以利用这一点来实现是否成功打开APP检测及回调。来自参考文章。代码如下:
// 模拟检测跳是否转到APP
let checkOpen = function (callBack) {
let clickTime = +(new Date());
function check(elsTime) {
// 判断定时器是否大于3000ms or 浏览器是否切换到手机的后台
if (elsTime > 3000 || document.hidden || document.webkitHidden) {
callBack(1);
} else {
callBack(0);
}
}
// 启动间隔20ms运行的定时器,并检测累计消耗时间是否超过3000ms,超过则结束
let count = 0,
timer;
timer = setInterval(() => {
count++;
let elsTime = +(new Date()) - clickTime;
if (count >= 100 || elsTime > 3000) {
clearInterval(timer);
check(elsTime);
}
}, 20);
}
checkOpen(function (opened) {
if (opened === 0) {
console.log("跳转失败!!!!");
}
else if(opened === 1){
console.log("跳转成功!!!!");
}
});
4、输入框设置属性type = number
问题说明:设置
type = 'number'的时候,maxlength不起效,当设置这个属性,可以用以下的css去掉默认样式
// HTML5去掉输入框type为number时的上下箭头的实现方法
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
appearance: none;
margin: 0;
}
input {
-moz-appearance: textfield;
}
5、动态加载css
代码如下:
function loadCss(url) {
var css = document.createElement('link');
if (!url) {
return;
}
css.type = 'text/css';
css.rel = 'stylesheet';
css.href = url;
document.getElementsByTagName("head")[0].appendChild(css);
}
6、动态加载js
代码如下:
function loadJs(url, callback) {//链接、回调
var done = false,
script = document.createElement('script');
if (!url) {
return;
}
script.type = 'text/javascript';
script.src = url;
script.onload = script.onreadystatechange = function () {
if (!done && (!script.readyState || script.readyState == 'loaded' || script.readyState == 'complete')) {
done = true;
script.onload = script.onreadystatechange = null;
if (callback) {
callback();
}
}
};
document.getElementsByTagName('head')[0].appendChild(script);
}
7、针对高德地图marker绑定点击事件
问题说明:在移动端中,通过请求动态渲染高德地图API标记的图标,并且绑定点击事件,触发不了里面的逻辑。 解决方案:在点击事件里面,添增一个setTimeout延迟处理
代码如下:
var marker = new AMap.Marker({
title: 'default-marker-1',
icon: new AMap.Icon({
size: new AMap.Size(51, 59), //图标大小
image: "/static/images/app-module/sticker/node-1.png",
imageOffset: new AMap.Pixel(0, 0)
}),
position: [113.323816, 23.110288]
});
marker.setMap(map);
marker.on('click', markerClick);
function markerClick(e) {
setTimeout(() => {
// 业务逻辑
}, 0);
}