H5页面在webview中打开文件选择框

274 阅读2分钟

在客户端应用中通过内嵌的html页面打开时,发生文件选择框出现在应用下方的现象,最小化应用后才能看见文件选择框。

1.定位原因

image.png

html页面中通过<input type="file" />打开文件选择框,导致应用焦点丢失、文件选择框被“压”到应用下层 的问题。

如上图所示,正常打开文件后聚焦在文件系统上,文件选择框出现在应用的上方。但是如果焦点还是在应用上时,就会出现文件选择框被覆盖的情况,对于用户来说,感觉就是点了文件选择框没反应。

2. 解决方案

使用客户端提供的jsBridge打开文件

不再使用<input type="file" />进行文件操作,使用webview提供的JsToNative替换input的change方法。

但是该方式的回调中只能返回base64格式或filePath。

如果在原有的逻辑中有文件上传操作,需要将文件对应的File对象上传到服务器,有两种方式。

  1. 将文件上传逻辑转移到客户端内实现

File 对象是 JavaScript(准确说是 Web API)特有的对象,由浏览器环境中的 Web API 提供,并不是通用的编程语言内置类型。

  1. 将base64格式的文件转为File对象
function base64ToFile(base64, filename) {
  const arr = base64.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]); // base64 解码为字符串
  let n = bstr.length;
  const u8arr = new Uint8Array(n);

  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }

  return new File([u8arr], filename, { type: mime });
}

🧠 拓展:如果你想转为 Blob 对象而不是 File

function base64ToBlob(base64) {
  const arr = base64.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
}