小程序 input(输入框) 固定在底部 获取焦点 上推页面

使用fixed定位将input固定在屏幕底部,同时为了不让页面整体上移,需要将input的adjust-position属性设为false。

只是,这么做的话会导致底部的输入框也无法上移。 从而被拉起的小键盘盖住。

从官方社区整理来一个方法,能够在小键盘拉起的同时将底部的input框顶起,同时适配大部分机型。

 

 

wxml

<view class='pocket_input' style='bottom:{{height}}px;' wx:if="{{inputShow}}" >

<input type='text' placeholder-style='input-placeholder' cursor='{{cursor_position}}' class='input_style' placeholder='随便说点什么吧~(30字以内哦)' focus='{{focus}}' cursor-spacing="2" adjust-position='{{adjust_position}}' maxlength='30' bindfocus="bindfocus" bindblur="bindblur" bindconfirm="bindconfirm"></input>

</view>

wxss

.pocket_input {

position: fixed;

bottom: 0;

width: 100%;

background-color: white;

overflow: hidden,

}

.input_style{

margin: 12rpx 23rpx;

background-color: #F4F5F6;

font-size: 30rpx;

border-radius: 20rpx;

padding-left: 15rpx;

}

 

.input-placeholder{

margin-left: 25rpx;

}

js

//监听input获得焦点

bindfocus: function(e) {

let that = this;

let height = 0;

let height_02 = 0;

wx.getSystemInfo({

success: function (res) {

height_02 = res.windowHeight;

}

})

 

height = e.detail.height - (app.globalData.height_01 - height_02);

console.log('app is', app.globalData.height_01);

that.setData({

height: height,

})

console.log('获得焦点的 e is', e);

},

//监听input失去焦点

bindblur: function(e) {

this.setData({

height: 0,

inputShow: false,

});

console.log('失去焦点的 e is', e);

},

我的页面效果设计是  

点击讨论  

然后让input获得焦点,

同时动态更改这个放置input的view的bottom属性,

做到input会随着小键盘的拉起, 被顶到小键盘的上方的效果。

 

这里有两点需要注意,第一点就是这个bottom值的获取,在input获得焦点的监听事件里,

e.detail.height  这个属性就是小键盘的拉起高度,获得这个值,然后bottom该值的高度。

只是做到这里你会发现,不同的机型,可能有的正好合适,有的

下方会有大块的留白,尤其IOS这样

 

原因是,

如果用的是小程序里的tarBar的话,(就app.json里配置那种),

此处是会自动加上这个高度的。

所以要把这个高度减去。

input才会随着小键盘拉起被顶到一个刚好合适的位置

方法如下

 

效果诸君亲测吧,有需要改进的地方请在下方留言

<think>我们正在处理一个关于Vue.js组件在iOS小程序输入框获取焦点后位置错乱的问题。 根据用户描述,问题发生在iOS环境下,当输入框获取焦点时,位置出现错乱。 这个问题通常与iOS的软键盘弹出行为以及页面滚动有关。 可能的原因和解决方案: 1. iOS下软键盘弹出会改变视口高度,可能导致页面元素被挤压或错位。 2. 输入框获取焦点时,iOS可能会自动滚动页面以使输入框位于可视区域,但有时滚动位置不正确。 常见的解决方案包括: a. 在输入框获取焦点时,手动调整滚动位置。 b. 使用CSS固定布局,避免页面被压缩。 c. 在Vue组件中监听输入框的focus事件,并触发滚动调整。 由于问题发生在小程序中,我们还需要考虑小程序环境的特点(例如微信小程序)。 步骤: 1. 确保页面布局使用合适的CSS,例如避免使用绝对定位或固定定位可能导致的问题。 2. 在输入框的focus事件中,手动触发滚动,将输入框滚动到可视区域。 具体实现: 在Vue组件中,我们可以给输入框添加一个ref,然后在focus事件中调用scrollIntoView方法。 例如: ```html <template> <input ref="myInput" @focus="handleFocus" /> </template> <script> export default { methods: { handleFocus() { // 使用setTimeout确保在iOS上执行滚动 setTimeout(() => { this.$refs.myInput.scrollIntoView({ behavior: 'smooth', block: 'center' }); }, 100); } } } </script> ``` 注意:scrollIntoView方法在大多数现代浏览器中都支持,但在小程序中可能有所不同。如果是在微信小程序中,我们可以使用小程序的API来实现。 如果是微信小程序,并且使用了原生组件(如input),我们可以使用wx.pageScrollTo方法。 在微信小程序中,我们可以在Vue组件中(假设使用mpvue或uni-app)这样处理: 对于mpvue或uni-app,我们可以这样: 在uni-app中,我们可以使用uni.pageScrollTo方法: ```javascript handleFocus() { // 获取输入框的位置信息 const query = uni.createSelectorQuery().in(this); query.select('.input-class').boundingClientRect(data => { if (data) { uni.pageScrollTo({ scrollTop: data.top, // 可以根据需要调整位置 duration: 300 }); } }).exec(); } ``` 但是,需要注意的是,iOS上软键盘弹出会改变窗口高度,因此可能需要动态计算。 另一个常见做法是禁止页面的滚动,然后当输入框聚焦时,将整个页面滚动到顶部,然后让输入框自然定位。但这可能不适用于所有情况。 此外,还可以尝试CSS解决方案: 在iOS上,可以尝试在全局样式中添加: ```css body { -webkit-overflow-scrolling: touch; } ``` 或者,针对输入框的容器: ```css .container { position: fixed; top: 0; left: 0; right: 0; bottom: 0; overflow-y: auto; } ``` 但是,固定定位可能会带来其他问题。 由于问题描述为“位置错乱”,可能是指输入框被键盘顶起时位置跳动。在iOS上,有时需要确保页面有足够的滚动空间,并且输入框不要位于页面底部。 综合建议: 1. 尝试使用scrollIntoView方法(在H5环境中),或者在小程序中使用对应的滚动API。 2. 检查布局,确保输入框所在的容器可以正确滚动。 3. 在iOS上,软键盘弹出时,页面内容可能会被压缩,可以尝试将页面设置为固定高度,并内部可滚动。 如果问题仍然存在,可能需要更详细的信息,例如具体的代码结构和小程序框架(mpvue, uni-app等)。 由于用户提到是嵌入在小程序中,因此我们需要按照小程序的环境来处理。 考虑到用户可能使用的是uni-app(因为它支持Vue语法且跨小程序),以下给出一个uni-app的示例: 在uni-app中,我们可以使用以下方法: 步骤: 1. 给输入框添加一个类名或id,用于获取位置。 2. 在focus事件中,使用uni.createSelectorQuery获取输入框的位置。 3. 使用uni.pageScrollTo将输入框滚动到合适位置。 代码示例: ```html <template> <view> <input class="my-input" @focus="focusInput" /> </view> </template> <script> export default { methods: { focusInput() { // 延时以确保键盘弹出后获取位置 setTimeout(() => { const query = uni.createSelectorQuery().in(this); query.select('.my-input').boundingClientRect(rect => { if (rect) { // 计算目标滚动位置,这里我们让输入框滚动到屏幕中间偏上的位置 const scrollTop = rect.top + uni.getSystemInfoSync().windowHeight / 2 - 100; uni.pageScrollTo({ scrollTop: scrollTop, duration: 300 }); } }).exec(); }, 100); } } } </script> ``` 注意:上面的代码中,我们通过计算将输入框定位到屏幕中间偏上,具体偏移量可以根据实际情况调整。 另外,还有一种情况是输入框被键盘遮挡,所以需要滚动到键盘上方。在iOS上,键盘是从底部弹出的,因此我们需要确保输入框不被键盘覆盖。我们可以将输入框滚动到页面底部键盘高度的位置。 但是,在微信小程序中,我们可以通过监听键盘高度变化事件来动态调整: 在页面的生命周期中监听键盘高度变化: ```javascript onShow() { uni.onKeyboardHeightChange(res => { this.keyboardHeight = res.height; }); } ``` 然后在输入框focus时,结合键盘高度计算需要滚动的距离。 不过,上面的方法可能比较复杂,且需要处理多个输入框的情况。 鉴于问题可能由多种因素引起,建议先尝试简单的滚动方法,再逐步调整。 最后,如果问题仍然无法解决,可以考虑使用第三方组件(如vant-weapp)中的输入框组件,它们通常已经处理了这些兼容性问题。 总结解决方案: 1. 使用CSS固定布局,避免页面被压缩。 2. 在输入框获取焦点时,使用API手动滚动页面,确保输入框在可视区域。 3. 考虑使用成熟的UI框架,避免自己处理兼容性问题。 由于问题描述不够详细(如具体的小程序框架、页面结构等),以上提供的是通用解决方案。 </think> ### 解决 iOS 上 Vue.js 组件输入框获取焦点后位置错乱的问题 在 iOS 设备上,当 Vue.js 组件中的输入框获取焦点时出现位置错乱,通常是由 **软键盘弹出时的布局重排** 和 **iOS 的滚动行为差异** 导致。以下是系统性的解决方案: #### 1. 修复 CSS 视口问题 (关键步骤) iOS 软键盘会改变视口尺寸,添加以下 meta 标签防止页面缩放: ```html <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> ``` 在全局 CSS 中: ```css body { position: fixed; /* 防止页面跳动 */ width: 100%; height: 100%; overflow: auto; /* 允许滚动 */ -webkit-overflow-scrolling: touch; /* 启用顺滑滚动 */ } ``` #### 2. 使用 Vue 指令自动滚动输入框 创建自定义指令确保输入框可见: ```javascript // main.js Vue.directive('scroll-to-focus', { inserted(el) { el.addEventListener('focus', () => { setTimeout(() => { el.scrollIntoView({ behavior: 'smooth', block: 'center' // 垂直居中 }); }, 300); // 等待键盘弹出 }); } }); ``` 在组件中使用: ```html <input v-scroll-to-focus v-model="inputValue"> ``` #### 3. 针对微信小程序的特殊处理 如果是嵌入微信小程序,在 `page.js` 中: ```javascript onPageScroll(e) { if (this.inputFocused) { wx.pageScrollTo({ scrollTop: e.scrollTop + 100, // 额外偏移量 duration: 0 }); } }, methods: { handleFocus() { this.inputFocused = true; setTimeout(() => { wx.pageScrollTo({ scrollTop: 9999 }); // 触发重排 }, 100); } } ``` #### 4. 预防性 CSS 措施 ```css .input-container { transform: translateZ(0); /* 启用 GPU 加速 */ will-change: transform; /* 提示浏览器优化 */ } /* 修复 iOS 15+ 的弹性滚动问题 */ @supports (-webkit-touch-callout: none) { body { overscroll-behavior-y: contain; } } ``` #### 5. 状态管理优化(结合 Vuex) 当使用 Vuex 管理全局状态时[^1],确保组件更新不影响布局: ```javascript // store.js export default new Vuex.Store({ state: { inputPosition: null }, mutations: { setInputPosition(state, pos) { state.inputPosition = pos } } }) // 组件内 methods: { savePosition() { this.$store.commit('setInputPosition', this.$el.getBoundingClientRect() ) } } ``` > **关键原理**:iOS 软键盘弹出会触发 `resize` 事件,但不会触发 `scroll` 事件,导致布局计算错误。通过强制滚动+CSS 固定视口可解决 90% 的案例[^2]。 ---
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

97pra

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值