blog icon indicating copy to clipboard operation
blog copied to clipboard

移动端 input 输入框 键盘 遮挡 遮盖

Open yongheng2016 opened this issue 5 years ago • 0 comments

input 标签在 iOS 上唤起软键盘,键盘收回后页面不回落(部分情况页面看上去已经回落,实际结构并未回落)

input 焦点失焦后,ios 软键盘收起,但没有触发 window resize,导致实际页面 dom 仍然被键盘顶上去--错位。解决办法:全局监听 input 失焦事件,当触发事件后,将 body 的 scrollTop 设置为 0。

document.addEventListener('focusout', () => {
  document.body.scrollTop = 0;
});

唤起软键盘后会遮挡输入框

当 input 或 textarea 获取焦点后,软键盘会遮挡输入框。解决办法:全局监听 window 的 resize 事件,当触发事件后,获取当前 active 的元素并检验是否为 input 或 textarea 元素,如果是则调用元素的 scrollIntoViewIfNeeded 即可。

window.addEventListener('resize', () => {
  // 判断当前 active 的元素是否为 input 或 textarea
  if (
    document.activeElement!.tagName === 'INPUT' ||
    document.activeElement!.tagName === 'TEXTAREA'
  ) {
    setTimeout(() => {
      // 原生方法,滚动至需要显示的位置
      document.activeElement!.scrollIntoView();
    }, 0);
  }
});

唤起键盘后 position: fixed;bottom: 0px; 元素被键盘顶起

解决办法:全局监听 window 的 resize 事件,当触发事件后,获取 id 名为 fixed-bottom 的元素(可提前约定好如何区分定位在窗口底部的元素),将其设置成 display: none。键盘收回时,则设置成 display: block;。

const clientHeight = document.documentElement.clientHeight;
window.addEventListener('resize', () => {
  const bodyHeight = document.documentElement.clientHeight;
  const ele = document.getElementById('fixed-bottom');
  if (!ele) return;
  if (clientHeight > bodyHeight) {
    (ele as HTMLElement).style.display = 'none';
  } else {
    (ele as HTMLElement).style.display = 'block';
  }
});

点击网页输入框会导致网页放大通过 viewport 设置 user-scalable=no 即可,(注意:当 user-scalable=no 时,无需设置 minimum-scale=1, maximum-scale=1,因为已经禁止了用户缩放页面了,允许的缩放范围也就不存在了)。代码如下:

<meta
  name="viewport"
  content="width=device-width,initial-scale=1.0,user-scalable=0,viewport-fit=cover"
/>

webview 通过 loadUrl 加载的页面运行时却通过第三方浏览器打开,代码如下

// 创建一个 Webview
Webview webview = (Webview) findViewById(R.id.webView);
// 调用 Webview loadUrl
webview.loadUrl("http://www.baidu.com/");

解决办法:在调用 loadUrl 之前,设置下 WebviewClient 类,当然如果需要也可自己实现 WebviewClient(例如通过拦截 prompt 实现 js 与 native 的通信)

webview.setWebViewClient(new WebViewClient());

yongheng2016 avatar May 06 '20 03:05 yongheng2016