技术分享
首页
  • JavaScript

    • 构造函数和原型
    • Cookie和Session
    • Object.create(null)和{}
    • TypeScript配置
    • typescript入门到进阶
  • 框架

    • Vue-Router
    • React基础入门
  • 其它

    • Http协议
    • 跨域问题总结
  • 分析Promise实现
  • Axios源码分析
  • Webpack原理
  • vueRouter源码分析
  • Vue

    • Vite快速搭建Vue3+TypeScript项目
    • Cordova打包Vue项目的问题
    • Vue将汉字转为拼音,取出首字母
    • h5项目问题总结
  • JavaScript

    • new Function
  • 后端

    • Node.js中使用Crypto生成Token
    • Body-Parser处理多层对象的问题
  • 其它

    • 项目Demo汇总
    • Vuepress+Vercel搭建个人站点
    • 项目中能用到的
    • husky规范代码提交
  • Mongoose基础
  • Multer文件上传中间件的使用
  • JavaScript

    • 浅谈两数全等
    • JavaScript进制转换
    • 手写bind,apply,call和new
  • 算法

    • 数组去重和排序
    • 数组扁平化
    • 斐波那契数列
  • JavaScript 数据结构
  • 其它

    • webpack面试题
    • vite面试题
    • svg和canvas的优缺点
    • TypeScript面试题
    • Vue常见面试题
  • 计算机网络

    • 数据链路层
    • 网络层
  • Git的使用
  • Nginx的使用
  • CentOS7安装Nginx
  • 正则表达式
  • SEO搜索引擎优化
  • Serverless介绍
友链
GitHub (opens new window)

刘誉

总有人要赢,为什么不能是我
首页
  • JavaScript

    • 构造函数和原型
    • Cookie和Session
    • Object.create(null)和{}
    • TypeScript配置
    • typescript入门到进阶
  • 框架

    • Vue-Router
    • React基础入门
  • 其它

    • Http协议
    • 跨域问题总结
  • 分析Promise实现
  • Axios源码分析
  • Webpack原理
  • vueRouter源码分析
  • Vue

    • Vite快速搭建Vue3+TypeScript项目
    • Cordova打包Vue项目的问题
    • Vue将汉字转为拼音,取出首字母
    • h5项目问题总结
  • JavaScript

    • new Function
  • 后端

    • Node.js中使用Crypto生成Token
    • Body-Parser处理多层对象的问题
  • 其它

    • 项目Demo汇总
    • Vuepress+Vercel搭建个人站点
    • 项目中能用到的
    • husky规范代码提交
  • Mongoose基础
  • Multer文件上传中间件的使用
  • JavaScript

    • 浅谈两数全等
    • JavaScript进制转换
    • 手写bind,apply,call和new
  • 算法

    • 数组去重和排序
    • 数组扁平化
    • 斐波那契数列
  • JavaScript 数据结构
  • 其它

    • webpack面试题
    • vite面试题
    • svg和canvas的优缺点
    • TypeScript面试题
    • Vue常见面试题
  • 计算机网络

    • 数据链路层
    • 网络层
  • Git的使用
  • Nginx的使用
  • CentOS7安装Nginx
  • 正则表达式
  • SEO搜索引擎优化
  • Serverless介绍
友链
GitHub (opens new window)
  • 项目 Demo 汇总
  • node中使用crypto生成token
  • new Function
  • body-parser处理多层对象的问题
  • Vite快速搭建Vue3+TypeScript项目
  • Cordova打包Vue项目的问题
  • Vue将汉字转为拼音,取出首字母
  • 项目中能用到的
  • Vuepress+Vercel搭建个人站点
  • husky规范代码提交
  • h5项目问题总结
    • ios 和 android 键盘弹起的区别
      • 区别
      • 问题
    • 附件下载
  • vue动态换行,行末省略
  • mocks项目复盘
  • 项目
coderly
2021-11-30

h5项目问题总结

# h5 项目问题总结

记录写 h5 页面遇到的一些问题以及解决方法

# ios 和 android 键盘弹起的区别

# 区别

  1. ios 键盘弹起会造成页面向上滚动(整个 html 页面移动),android 键盘弹起是键盘覆盖在视口上(html 页面不会移动,视口区域变化所以会触发 resize 事件)
  2. android 键盘弹起会触发页面的 resize 事件(ios 不会),ios 在键盘收起的时候 input 会失去焦点(安卓不会,使用原生 input 框的情况)
  3. ios 在键盘弹起时页面滚动,收起时可能回不到原来的位置(android 不会)

# 问题

# android 键盘弹起时 input 框不遮挡

描述:

ios 中 focus 触发时,页面会向上滚动,input 出现在视口位置,不存在遮挡问题
android 中 focus 触发时,整个视口高度变宽,input 有可能会被遮挡

解决:

  1. ios 中几乎不用做处理
  2. android 中通过监听 focus 事件,将 输入框滚动到视口位置(或者将元素定位到键盘上方)
// TODO: 待完善
1

# 监听键盘的收起状态

描述:

ios 触发软键盘上的“收起”按钮键盘或者输入框以外的页面区域时,输入框失去焦点,软键盘收起。
android 触发软键盘上的“收起”按钮键盘或者输入框以外的页面区域时,软键盘收起,但输入框没有失去焦点。

解决:

  1. ios 上通过监听 focus、blur 事件来获取键盘的状态
  2. android 上键盘弹起和收起状态时,会触发页面的 resize 事件,所以通过监听 resize 事件可以知道键盘收起(focus 触发的前提)
// 监听输入框的软键盘弹起和收起事件
function listenKeybordStatus($input) {
  const _input = document.getElementById("input");
  if ("ios") {
    // 自行判断
    // IOS 键盘弹起:IOS 和 Android 输入框获取焦点键盘弹起
    _input.addEventListener(
      "focus",
      function() {
        console.log("ios 键盘弹起啦!");
        // TODO
      },
      false
    );

    // IOS 键盘收起:IOS 点击输入框以外区域或点击收起按钮,输入框都会失去焦点,键盘会收起
    _input.addEventListener("blur", () => {
      console.log("ios 键盘收起啦!");
      // TODO
    });
  }

  // android 键盘收起:android 键盘弹起或收起页面高度会发生变化
  if ("android") {
    // 自行判断
    let originHeight =
      document.documentElement.clientHeight || document.body.clientHeight;

    window.addEventListener(
      "resize",
      function() {
        const resizeHeight =
          document.documentElement.clientHeight || document.body.clientHeight;
        if (originHeight < resizeHeight) {
          console.log("android 键盘收起啦!");
          // TODO
        } else {
          console.log("android 键盘弹起啦!");
          // TODO
        }

        originHeight = resizeHeight;
      },
      false
    );
  }
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# ios 键盘弹起页面可滚动

描述:

在 ios 中,键盘弹起状态,页面还可以滚动
android 中没有这个情况

解决:

  1. ios 中在键盘弹起时,给页面添加 touchmove 事件触发后收起键盘(引出的问题:键盘弹起时页面的 长按时间也会触发 touchmove)
  2. ios 中用户滚动页面的时候,手动触发 blur
  3. 暂时未能做到 ios 在键盘弹起的时候,禁用页面滚动,只能通过这种方式来换个思路解决问题
document.body.addEventListener("touchmove", onTouchMove.bind(this));
// 手动失焦
function onTouchMove() {
  document.getElementById("input").blur();
}
1
2
3
4
5

# android 中定位在页面右下角的元素在键盘弹起时未消失

描述:

需求中需要在页面右下角定位入口元素的情况
此时键盘弹起时,在 ios 中定位元素会消失,在 android 中 定位元素不消失,且会跟着键盘弹起而向上移动

效果
图片

解决:

  1. android 中键盘弹起会触发 resize 事件,判断触发前后视口的高度
// 适配安卓键盘弹出定位问题
const initInnerHeight = window.innerHeight;
window.addEventListener("resize", () => {
  const showContact = window.innerHeight >= initInnerHeight; // 隐藏定位元素
  document.getElementById("contact").style.display = showContact ? "" : "none";
});
1
2
3
4
5
6

# ios 底部 safe area 问题

描述:

部分 ios 机型 存在 safe area
主要表现在底部会有一个居中的黑条,效果如下
页面内容布局不想被 黑条 遮挡,就可以使用 ios 提供的 api 来改变页面布局

效果
图片

解决:

  1. 使用到的属性
    • safe-area-inset-left:安全区域距离左边边界的距离
    • safe-area-inset-right:安全区域距离右边边界的距离
    • safe-area-inset-top:安全区域距离顶部边界的距离
    • safe-area-inset-bottom :安全距离底部边界的距离
/* 设置 padding-bottom 的像素,使元素内容不会出现在 小黑条 区域 */
padding-bottom: constant(safe-area-inset-bottom); /* 兼容 iOS < 11.2 */
padding-bottom: env(safe-area-inset-bottom); /* 兼容 iOS >= 11.2 */
1
2
3

# 计算页面滚动距离

描述:

h5 中未设置 overflow: auto,属性,但页面滚动了

解决:

const len = window.pageYOffset || document.documentElement.scrollTop || 0;
1

# 附件下载

流文件下载
请求头需要添加 responseType: 'blob'
描述:

响应头中带有 Content-Type: application/octet-stream(有 stream 等明显标记的)
附件下载分为 get 和 post 下载

get 下载:

  1. 触发浏览器对无法解析的文件会进行下载
window.open(downloadUrl); // 方式一
1
<a href="downloadUrl">点击下载</a>
1

post 下载:

  1. 通过 URL.createObjectURL 创建 一个指向源 Object 的 URL 对象
  2. 将该 URL 对象 赋值给 a 标签,再触发 下载
axios({
  url: "downloadUrl",
  method: "POST",
  data: {
    analysisId: "analysisId",
  },
  responseType: "blob",
})
  .then((res) => {
    const blob = new Blob([res], {
      type: "text/csv",
    });
    const URL = window.URL || window.webkitURL || window.moxURL; // 兼容
    // 创建下载链接,会将文件存在内存中
    const blobUrl = URL.createObjectURL(blob);
    // 构建 a 标签
    const a = document.createElement("a");
    a.download = "分析数据.xlsx";
    a.href = blobUrl;
    document.body.appendChild(a);
    // 触发 a 标签的点击,自动下载
    a.click();
    // 释放下载链接,删除内存中的文件
    URL.revokeObjectURL(a.href);
    document.body.removeChild(a);
  })
  .catch((err) => {
    console.log("下载失败:", err);
  });
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
29
上次更新: 2021/12/10, 14:32:24
husky规范代码提交
vue动态换行,行末省略

← husky规范代码提交 vue动态换行,行末省略→

最近更新
01
代码片段
04-22
02
koa全家桶
03-29
03
mocks项目复盘
03-29
更多文章>
Theme by Vdoing | Copyright © 2021-2022 coderly | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式