加载中...
移动端开发H5页面,各种问题介绍
发表于:2023-06-03 | 分类: 前端

移动端如何进行适配

  1. 使用 viewprot 配合 vw/vh。
    首先给 html 文件增加 viewport 配置
<meta
  name="viewport"
  content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>

然后利用插件postcss-px-to-viewport,根据设计稿的尺寸配置视口的宽高。然后该插件在构建过程中就会将 px 转成 vw。

  1. 使用 viewport 配合 rem;
    rem 是以 html 元素的 font-size 为单位的尺寸;

首先给 html 文件增加 viewport 配置,将布局视口调整为设备的可视宽高

<meta
  name="viewport"
  content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>

假设设计稿是按照 iphone6 来设计的,那么设计稿中采用的应该是750*1334px的物理像素;

那么,我们可以设置 html 根元素的尺寸为font-size: 100px;

为什么是 100px?定为 100px 的话,我们就是将 750 的设计稿分成了 7.5rem,1rem 为 100px;

所以,根元素的字体为 100px;

document.documentElement.style.fontSize = 750 / 7.5;

但是到了不同尺寸的手机中,根元素就不能为 100px 了,但是我们还是希望简单的使用 设计稿物理像素 / 100 = ?rem 的方式计算出元素的 rem。那么字体就需要根据不同的手机的逻辑像素(视口宽度)来计算;

document.documentElement.style.fontSize = (screen.width / 750) * 100 + "px";

这样,在项目中就可以愉快的将所有设计稿尺寸除以 100 来算 rem 了

移动端 input 内的文字和同行文本在 android 中不对齐

<div class="wrap">
  <input type="text" pattern="[0-9]*" />
  <span>其他内容</span>
  <div></div>
</div>

这个问题在 ios 中是不存在的,并且如果将 input 和同行的文本都设置高度和 line-height,虽然在 android 中会对齐,但是 ios 中 input 内的文字又会往下掉。。。所以,我使用了两套 css,ios 中不处理,android 中增加居中的一些样式

const isIPhone = new RegExp("\\biPhone\\b|\\biPod\\b", "i").test(
  window.navigator.userAgent
);

移动端滚动穿透

当某个页面高度超过了屏幕并且可以滚动,且这个页面中有模态框。当模态框打开后,底下的页面还是可以滚动。可以使用一下的方法来解决

const fixScroll = (function () {
  const oBody = document.getElementsByTagName("body")[0];
  return function (visible) {
    if (visible) {
      oBody.style.position = "fixed";
      oBody.style.overflow = "hidden";
    } else {
      oBody.style.position = "static";
      oBody.style.overflow = "visible";
    }
  };
})();
// fixScroll(true) 在显示弹框的时候调用
// fixScroll(false) 在隐藏弹框的时候调用

H5 和 webview 回退刷新问题

项目是一个运行在 webview 中中的 h5 页面,在页面中需要跳转到第三方的页面,且回退后需要刷新页面。然后就遇到了 bfcache

什么是 bfcache

bfcache(back-forward cache),也可叫做“往返缓存”。是为了用户在使用浏览器的“返回”和“前进”按钮时,加快页面的转换速度。它实际上是将整个页面(数据、DOM、js)保存在了内存中。如果页面位于 bfcache 中,那么再次打开这个页面则不会触发 onload 事件

解决方案

Firefox 提供的思路

JS 监听 pageshow 事件阻止页面进入 bfcache

window.addEventListener("pageshow", function (e) {
  if (e.persisted) {
    window.location.reload();
  }
});

关于 ios 下通过 navigator.geolocation.getCurrentPosition 获取经纬度信息

在 ios 中,需要使用 https,才能调用 navigator.geolocation.getCurrentPosition 获取经纬度信息。

可以通过 iframe 的方式绕过 ios 的限制(但是无法绕过谷歌浏览器的限制)

var options = {
  enableHighAccuracy: true,
  maximumAge: 30000,
  timeout: 12000,
};

window.showPosition = function (position) {
  console.log(position.coords.longitude);
  console.log(position.coords.latitude);
};
window.showError = function (error) {
  switch (error.code) {
    case error.PERMISSION_DENIED:
      alert("用户不允许地理定位!");
      break;
    case error.POSITION_UNAVAILABLE:
      alert("无法获取当前位置!");
      break;
    case error.TIMEOUT:
      alert("操作超时!");
      break;
    case error.UNKNOWN_ERROR:
      alert("未知错误!");
      break;
  }
};
window.locationCallback = function (err, position) {
  if (err) {
    showError(err);
    return;
  }

  showPosition(position);
};

var str =
  '<iframe src="javascript:(function(){ ' +
  "window.navigator.geolocation.getCurrentPosition(" +
  "function(position){parent && parent.locationCallback && parent.locationCallback(null,position);}, " +
  "function(err){parent && parent.locationCallback && parent.locationCallback(err);}, " +
  "{enableHighAccuracy : " +
  options.enableHighAccuracy +
  ", maximumAge : " +
  options.maximumAge +
  ", timeout :" +
  options.timeout +
  "})" +
  ';})()" style="display:none;"></iframe>';
var div = document.createElement("div");
div.innerHTML = str;
document.body.appendChild(div);
上一篇:
移动端开发H5页面,各种问题介绍
下一篇:
使用Typescript和rollup开发一个工具库,并使用github actions来自动发布npm包
本文目录
本文目录