锁定页面+Fixed + Input 调用键盘的时候位置偏移之小技巧

本文探讨了在移动端表单验证中,iOS设备上input元素获得焦点后页面偏移的问题。通过分析问题原因,提出了使用fixed锁定页面、passive修饰符及scrollTo方法的解决方案。

##      问题描述
     
最近在写移动端一个表单验证。用于要禁止下拉出现微信或者app浏览器显示默认信息。使用了fixed锁定页面,但是,但是在iOS下,input得到焦点调起键盘输入之后 ,页面input元素位置发生偏移。导致内容输入会出现问题+页面卡顿。最开始想到blur时,改变position值为fixed,focus为static;然鹅,不管用哇。。。
    
   

    
 ### 问题原因
    
         查阅资料后,算是有个小答案了,不过有待考证哈。。猜测在iOS中,当你点击input准备输入时,虚拟弹窗弹出。整个视窗的高度就会变成减去键盘的高度。加上我们的父元素加上了fixed,就会整体上移.

### 解决方案:
    
> 锁定页面js:
    
   

        在mounted加入事件监听,加上.passive修饰符。由于touchmove的默认行为是滚动当前页面或者缩放页面,所以我们要阻            止,锁定页面。让他静止不动,这里说下passive;


> passive:


    但是浏览器无法知道一个监听器会不会调用preventDefault(),它能做的只有等待监听器执行完之后再去执行默认行为。而监听器是要耗时的,有时会很明显。会导致页面卡顿。其实上80%的滚动不会阻止默认行为,也就是说浏览器白等了。passive出来后。他就可以在两个线程里同时执行监听器中
    的js代码和浏览器的默认行为了。
    
具体大家可以参考。这位大神的文章,由于addEventListener和正常事件的区别时不会前后覆盖。会同时执行,并且他接受3个参数:事件名+作出处理+(capture: Boolean, passive: Boolean, once: Boolean})
    

>css:
   

   css部分,我们最外层父级相对定位。页面form和logo绝对定位。此处需要特别注意。当你input调起iOS软键盘,输入之后,页   面高度并不会自动下移,会出现空白,
    需要触发才会恢复原来的样子。


    这里需要在用到input的地方添加blur事件,使用
      
 window.scrollTo(0, 0)**;将其位置恢复原状。
    


最后,算是解决啦,那个,就是使用正常布局+passive修饰符+scrollTo。解决的问题。

<think>好的,我现在需要帮助用户解决在微信小程序中实现input组件调用自定义键盘的问题。首先,我要回忆一下微信小程序的文档和相关知识。记得微信小程序input组件默认会触发系统键盘,但如果要使用自定义键盘,可能需要通过其他方式实现,比如模拟键盘的点击事件或者覆盖系统键盘。 接下来,我需要考虑用户的需求是什么。用户希望input组件能够调用自定义键盘,而不是系统自带的。这可能涉及到如何阻止系统键盘的弹出,同时显示自定义的键盘组件,并通过点击自定义键盘的按钮来输入内容。 然后,我需要查阅相关的引用资料。引用2提到了input组件的基础和高级用法,可能有一些属性可以控制键盘行为。引用3和引用4提到了自定义导航栏和键盘高度变化的事件处理,这可能对调整自定义键盘位置有帮助。引用1提到了使用formdata的问题,但可能和当前问题关联不大。 首先,微信小程序input组件有一个属性叫做cursor-spacing,可以设置光标与键盘的距离,但默认情况下input被点击时会自动弹出系统键盘。如果要禁用系统键盘,可能需要将input设置为disabled或者read-only,但这样用户就无法输入了,所以需要结合自定义键盘组件来实现输入。 可能的步骤是: 1. 创建一个自定义的键盘组件,包含数字或其他需要的按键。 2. 当用户点击input时,阻止系统键盘弹出,显示自定义键盘。 3. 将自定义键盘的输入内容同步到input中。 但如何阻止系统键盘弹出呢?如果input设置为disabled,用户无法聚焦,但可能无法触发点击事件。另一种方法是使用read-only属性,这样用户点击input时可以触发事件,但不会弹出系统键盘。然后通过监听input的点击事件,显示自定义键盘。 然后,自定义键盘需要处理按键点击,将值传递给input组件。可能需要通过事件传递或者父子组件通信来实现。 引用4提到自定义组件的事件绑定,比如bindcustomevent,这可能用于自定义键盘组件触发输入事件,将值传递给父页面。 另外,引用3提到了键盘高度变化的事件,可能需要在显示自定义键盘时调整其位置,避免被系统键盘遮挡,但如果是自定义键盘,可能需要自己控制其位置,比如固定在底部。 综合这些信息,实现步骤可能是: 1. 创建自定义键盘组件,包含所需的按键布局。 2. 在页面input组件上设置read-only属性,并绑定点击事件,当点击时显示自定义键盘。 3. 自定义键盘通过事件传递输入的值到页面,更新input的value。 4. 调整自定义键盘位置,确保不会被其他元素遮挡,可能使用绝对定位或固定在底部。 需要注意的是,在iOS和安卓上,read-only的input可能表现不同,需要测试。另外,自定义键盘可能需要处理退格、确认等操作,以及样式调整。 可能遇到的问题包括:如何隐藏系统键盘、如何处理多个input的切换、如何同步输入内容等。需要逐一解决。 现在,我需要将这些思考整理成一个清晰的步骤,并提供代码示例,同时回答相关问题。</think>### 微信小程序实现input组件调用自定义键盘的方法 #### 实现思路 1. **禁用系统键盘**:通过设置input组件的`disabled`或`read-only`属性,阻止系统键盘自动弹出。 2. **显示自定义键盘**:当用户点击input时,触发事件显示自定义键盘组件。 3. **输入同步**:通过组件间通信,将自定义键盘的输入内容同步到input中。 4. **布局调整**:利用`wx.onKeyboardHeightChange`监听键盘高度变化,避免自定义键盘被遮挡[^3]。 --- #### 实现步骤与示例代码 ##### 1. 创建自定义键盘组件 新建组件`custom-keyboard`,包含数字按键和功能键(如退格、确认): ```html <!-- components/custom-keyboard/index.wxml --> <view class="keyboard" style="bottom: {{keyboardBottom}}px"> <view class="row"> <button wx:for="{{1,2,3}}" bindtap="onKeyTap" data-value="{{item}}">{{item}}</button> </view> <!-- 其他行按键 --> <button bindtap="onBackspace">退格</button> </view> ``` ##### 2. 页面中使用input组件 设置`read-only`属性,点击时显示自定义键盘: ```html <!-- index.wxml --> <input value="{{inputValue}}" read-only bindtap="showCustomKeyboard" placeholder="点击输入" /> <custom-keyboard wx:if="{{showKeyboard}}" bindkeyevent="onKeyInput" bindbackspace="onBackspace" /> ``` ##### 3. 逻辑处理 ```javascript // index.js Page({ data: { inputValue: '', showKeyboard: false, }, showCustomKeyboard() { this.setData({ showKeyboard: true }); }, onKeyInput(e) { const value = this.data.inputValue + e.detail.value; this.setData({ inputValue: value }); }, onBackspace() { this.setData({ inputValue: this.data.inputValue.slice(0, -1) }); } }); ``` ##### 4. 处理键盘高度问题 监听键盘高度变化,调整自定义键盘位置: ```javascript // index.js onLoad() { wx.onKeyboardHeightChange((res) => { if (res.height > 0) { // 系统键盘弹出时隐藏自定义键盘 this.setData({ showKeyboard: false }); } }); } ``` --- #### 关键注意事项 - **兼容性**:`read-only`属性在部分安卓机型可能仍会触发系统键盘,需测试覆盖。 - **样式优化**:使用`position: fixed`将自定义键盘固定在底部。 - **输入验证**:在自定义键盘逻辑中加入输入类型限制(如仅数字)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值