微信小程序开发,当我们遇见input,textarea等输入文本框是,就会出现,软件盘遮挡或者页面上推,导致穿透navbar的情况,本来这种情况可以处理,奈何测试认为这是bug,必须要要改,这里就谈谈我的处理办法。
1 uniapp+vue+uview组件库 实现以上效果。
这里首先要说下页面上推的开启和关闭。再文本框微信api中是有一个属性的就是adjust-position这个属性如果这个属性为true则就是页面上推,如果页面上推,则就会导致整体页面上移,穿透navbar导航。注意这里说的是使用navbar不是微信小程序自带的导航。由于uview组件库中navbar的fixed属性默认都是true既是固定定位,所以通常情况下,我们页面比较高的时候,页面都是从他的下面穿过。正常是没有问题的。但是当页面整体被上推,这个fixed定位属性就会失效,无法固定再页面的顶部,也就是说也被整体上推了。
既让已经知道这个原因,那么我们来看看怎么去改。
目前比较确定的能实现的解决办法有两种,其他都是均无效或者说和我们要实现的效果不一致。
第一种:利用定位实现。即再关闭input的上推功能前提下,获取键盘高度后,将需要和键盘对其的页面底部定位到和软键盘高度的位置。这种情况适用比较间的的页面。
者请采用定位的方法,目前我的使用再android下没有问题,但是再ios下出出现了问题。所以这种解决方案我本人已经更改,改为第二种实现方法。
第二种,就是采用键盘唤起之后,获取键盘高度之后,我们给当前整体页面添加,paddingBottom或者height,去更改当前页面的高度,然后利用微信的wx.pageScrollTo接口滚动到当前位置去实现。
那么这里就有两个问题:
1 如何获取键盘的高度?
2 多个input,我们又该滚动到哪里呢?
如何获取键盘高度,有两种方案,第一种就是利用input的的focus事件,该事件对象有一个detail属性,属性下有个height属性。但是这个属性只有再正式环境下才能拿到,也即是我们平时的开发时候的开发板,体验版是无法拿到的。所以放弃这种方案。第二种就是利用onKeyboardHeightChange和offKeyboardHeightChange 微信提供的API实现。offKeyboardHeightChange这个是关闭监听的,所以要在页面销毁之前,关闭监听不然会导致内存溢出。
在这个onKeyboardHeightChange Api中我们可以拿到键盘的高度。不过这个API本身也是有缺点的,目前我的测试缺陷是。当手动关闭键盘的时候,拿到的高度不是0,而是键盘本身的高度。根据我的观察应该是键盘手动关闭的时候,确实触发了该API但是此时键盘并没有收回去,所以拿到的依然是原来键盘展开的高度。以我目前测试情况看,input获得焦点,触发该api开始,拿到的指分别是255,0,然后手动关闭键盘再来一个255,所以这样就会导致我们给页面增加的高度不会恢复。所以我们利用input框的blur事件,来恢复键盘高度。
那现在我们给页面增加了高度或者增加了paddingBottom,但是由于键盘唤起的时间早于onKeyboardHeightChange的执行时机,所以键盘唤起之后我们来设置高度或者padding,此时键盘已经显示在了页面上,这里智能保证不穿透了,但是键盘位置和当前input框的位置并不对应。所以接下来我们就需要通过滚动页面来实现滚动到指定位置。
页面滚动到指定位置:
我们需要给当前需要处理的input外层dom设置id,class也可以,然后我们利用在focus事件去获取当前的dom id,记录下来,然后我们在键盘被唤起之后,开始滚动页面到指定位置。这样就完美解决了这个问题。
pageScrollToBottom() {
if (this.pageId) {
wx.createSelectorQuery()
.in(this)
.select("#" + this.pageId)
.boundingClientRect((rect) => {
if (rect) {
// 使页面滚动到底部
wx.pageScrollTo({
scrollTop: rect.top + rect.height,
});
}
})
.exec();
}
},
效果如下:
当然这里还有一些小细节处理,这里简单说一下,
1 就是focus事件的执行时,我们去设置当前也买你需要滚动的dom id,紧着我们就要 我们利用onKeyboardHeightChange API去设置页面高度,紧着我们去滚动页面,此时会有一个小bug,就是第一次执行的时候,滚动方法内无法滚到合适位置。或者没有滚动,这个原因是因为我们给页focus 执行 到 onKeyboardHeightChange 知行事件非常短,也就是说我们改完高度,页面还没有去渲染完成高度呢,此时我们就去执行滚动,后面我们就正常了。
所以这块我们可以给一个默认值,我目前给的值是255,来实现第一次点击的时候也能滚动到指定位置。
pageset(pageId) {
console.log(pageId, "res focus");
this.pageId = pageId;
if (!parseInt(this.pagePadding)) {
this.pagePadding = "255px";
}
this.pageScrollToBottom();
},
2 目前经过测试ios上还有一些问题,主要就是会穿透navBar,需要给页面增加
page {
background-color: #f7f7f7;
background: #f7f7f7;
height: 100%;
overflow-y: hidden;
overflow-x: hidden;
}
3 注意uview组件库的版本,
我使用的是1.8.4,所以需要直接去该组件库的代码,增加adjust-position支持。
这其中关于android系统,ios系统,鸿蒙系统等各个版本方面兼容性问题比较多,需要调整的地方页比较多,暂时我这里也没有完全适配各个系统和版本。
希望后面有问题交流的我及时回复