移动端软键盘遮挡问题

本文介绍了如何解决移动端H5页面中输入框被软键盘遮挡的问题,探讨了iOS和Android系统的不同处理方式,主要利用scrollIntoView和scroll方法。在iOS中,通常无需特殊处理,而在Android中,可以通过监听window.onresize事件并调用scrollIntoView或scroll方法确保输入框始终在可视区域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

scrollIntoView 介绍

移动端的H5页面,当输入框元素获取焦点时,会吊起软键盘,如果输入框被软键盘遮挡了,则页面会发生滚动使输入框显示在可视区。浏览器这种默认处理机制在元素设置了绝对定位或设置了html,body{height:100%;}时可能会失效,通常需要手动处理。

防软键盘遮挡的处理思路:

  • IOS系统中,软键盘吊起时,整个 window 往上滚,window的宽高不变,不会触发window.onresize 事件。并且,软键盘始终不会遮挡输入框,所以在ios中不处理。有些版中的微信页面存在页面不回滚的bug,这个需要处理。

  • 安卓系统中,软键盘吊起时,window 不滚动,window的高度减小,减少值等于软键盘的高度,会触发 window.onresize 事件。如果输入框被遮挡,可使用 scrollIntoView 方法强制在可视区显示获取焦点的输入框元素。

让当前的元素滚动到浏览器窗口的可视区域内方法。 MDN
scrollIntoView() 浏览器支持度较高(推荐)。
scrollIntoViewIfNeeded() 部分浏览器支持,懒滚动模式。

scrollIntoView()
Element.scrollIntoView() 方法让当前的元素滚动到浏览器窗口的可视区域内。
这是一个实验中的功能,浏览器支持:PC端和移动端都支持

语法:

element.scrollIntoView();        // 等同于element.scrollIntoView(true) 
element.scrollIntoView(bool);    // Boolean型参数 
element.scrollIntoView(options); // Object型参数

bool 可选,一个Boolean值:如果为true,元素的顶端将和其所在滚动区的可视区域的顶端对齐。相应的 options: {block: “start”, inline: “nearest”}。这是这个参数的默认值。如果为false,元素的底端将和其所在滚动区的可视区域的底端对齐。相应的options: {block: “end”, inline: “nearest”}。
options 可选, 一个包含下列属性的对象:
behavior 可选,定义动画过渡效果, "auto"或 “smooth” 之一。默认为 “auto”。
block 可选,定义垂直对齐, “start”, “center”, “end”, “nearest”。默认为 “start”。
inline 可选,定义水平对齐, “start”, “center”, “end”, “nearest”。默认为 “nearest”。

var element = document.getElementById("box");

element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({
   block: "end"});
element.scrollIntoView({
   behavior: "instant", block: "end", inline: "nearest"});

scrollIntoViewIfNeeded()
Element.scrollIntoViewIfNeeded()方法用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。 如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。 此方法是标准的Element.scrollIntoView()方法的专有变体。

这是一个非标准的功能,浏览器支持:移动端几乎都支持
在这里插入图片描述
语法:

element.scrollIntoViewIfNeeded(); 
// 等同于element.scrollIntoViewIfNeeded(true) 

element.scrollIntoViewIfNeeded(false); 
element.scrollIntoViewIfNeeded(true); 

如果为true,则元素将在其所在滚动区的可视区域中居中对齐。
如果为false,则元素将与其所在滚动区的可视区域最近的边缘对齐。 根据可见区域最靠近元素的哪个边缘,元素的顶部将与可见区域的顶部边缘对准,或者元素的底部边缘将与可见区域的底部边缘对准。

示例:

var element = document.getElementById("child"); 

element.scrollIntoViewIfNeeded();
element.scrollIntoViewIfNeeded(true);
element.scrollIntoViewIfNeeded(false);

1.利用 scrollIntoView 实现防遮挡

1.针对某个元素单独处理

var inp = document.getElementById('inp');
//安卓中获取焦点时防遮挡
inp.onfocus = function(){
   
  if(this.scrollIntoViewIfNeeded){
   
    //懒滚动,当在可见区时不发生滚动,元素不再可见区时滚动到可见区中部
    this.scrollIntoViewIfNeeded(true);  
  }else{
   
    //无论怎样都会滚动到与可见区底部对齐
    this.scrollIntoView(false);           
  }  
}
//ios 中失去焦点时回滚
inp.onblur = function(){
   
   window.scrollTo(0, 0)
}

2.全局处理

//安卓中获取焦点时防遮挡
window.onresize = function () {
   
  if (document.activeElement.scrollIntoViewIfNeeded) {
   
    //懒滚动,当在可见区时不发生滚动,元素不再可见区时滚动到可见区中部
    document.activeElement.scrollIntoViewIfNeeded(true); 
  } else {
   
    //无论怎样都会滚动到与可见区底部对齐
    document.activeElement.scrollIntoView(false);
  }
}
//ios 中失去焦点时回滚
document.onkeyup = function(e){
   
   var name = e.target.tagName
   if (name != 'INPUT' && name != 'SELECT' && name != 'TEXTAREA') {
   
       window.scrollTo(0, 0)
   }
}

3.由于上面两种简单处理方式可能存在有些手机不触发等细节问题。推荐用下面这种方式。

<input type="text" onfocus="SV.focus(this)" name="">  
<script>
let SV = {
    
  _el:null,
  _isFocusNow:false,
  _ua:window.navigator.userAgent,
  _init:false,
  _scroll:function(){
    
  	var el = this._el;
  	if(!el) return false;
    if(el.scrollIntoViewIfNeeded){
    
      el.scrollIntoViewIfNeeded(true);    
    }else{
    
      el.scrollIntoView(false);           
    }	  	
  },
  _toTop:function(el){
    
  	var _t = this;
  	_t._isFocusNow = false;
	setTimeout
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值