2***@qq.com
2***@qq.com
  • 发布:2025-07-02 10:10
  • 更新:2025-07-02 10:21
  • 阅读:23

【报Bug】textarea/input组件 微信小程序 ios端 第一次聚焦后自动失焦

分类:uni-app

产品分类: uniapp/小程序/微信

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: window11

HBuilderX类型: 正式

HBuilderX版本号: 4.74

第三方开发者工具版本号: stable1.0.6.2409140

基础库版本号: 3.8.7

项目创建方式: HBuilderX

示例代码:
// bottom为键盘高度  bottom不为0时则键盘聚焦   
<template>  
    <view class="input-wrap flex col" :style="viewStyle">  
        <view class="flex align-center">  
            <view class="flex align-center" @tap="changeAnonymousFlag">  
                <image :src="NI_MING" mode="widthFix" class="niming-logo" v-if="anonymousFlag == 10"></image>  
                <view class="hide-box" v-else></view>  
                <text class="niming">匿名</text>  
            </view>  
            <textarea class="qx-input-content" cursor-spacing="20" auto-height v-model="content" confirm-type="send"  
                :confirm-hold="true" :show-confirm-bar="false" @confirm="send" :adjust-position="false"  
                @keyboardheightchange="keyboardHeightChange" placeholder="请输入消息..."  
                placeholder-class="placeholder-class" @blur="areaBlur" :maxlength="100" @focus="areaFocus"></textarea>  

            <view class="options-box relative flex col align-center" v-if="!showSendBtn">  
                <view class="relative">  
                    <view class="39size">  
                        <Agree size="39rpx" :params="{businessId:info.dynamicId,businessType}" ref="agreeRef"  
                            @change="agreeChange" :praiseFlag="info.praiseFlag"  
                            agreeUrl="/pagesCircle/static/input-agree.png" agreedUrl="/pagesCircle/static/agreed3.png"  
                            mode="heightFix" />  
                        <view class="tips-texts flex align-center" v-if="info.praiseNum > 0">  
                            <text>{{info.praiseNum}}</text>  
                        </view>  
                    </view>  
                </view>  
                <text>点赞</text>  
            </view>  
            <view class="options-box relative flex col align-center" v-if="!showSendBtn">  
                <view class="relative">  
                    <view class="39size">  
                        <button open-type="share" class="fill share-btn" @tap="forwardIt(info)"></button>  
                        <image :src="SHARE_LOGO_ICON" mode="heightFix" class="qx-logo">  
                        </image>  
                        <view class="tips-texts flex align-center share-tips-text" v-if="info.forwardNum > 0">  
                            <text>{{info.forwardNum}}</text>  
                        </view>  
                    </view>  
                </view>  
                <text>转发</text>  
            </view>  
            <view class="send-logo" v-if="showSendBtn" @tap="send">  
                <image :src="SEND_ICON" mode="widthFix"></image>  
            </view>  
        </view>  
    </view>  
</template>  

<script setup>  
    import { reactive, ref, computed } from 'vue';  
    import Agree from '@/components/Agree/Agree.vue';  
    import { SEND_ICON } from '@/util/static';  
    import { forwardIt } from '@/util/util';  

    const SHARE_LOGO_ICON = '/static/toast-share.png'  
    const NI_MING = '/static/detail-intro-ok.png'  

    const props = defineProps({  
        info: {  
            type: Object,  
            default: () => ({})  
        },  
        businessType: {  
            type: Number,  
            default: 10  
        }  
    })  

    const emits = defineEmits(['update:info', 'confirm'])  

    /**  
     * enum anonymousFlag  
     * 10   匿名  
     * 20   不匿名  
     */  
    const anonymousFlag = defineModel()  
    const changeAnonymousFlag = () => {  
        console.error(anonymousFlag.value)  
        if (anonymousFlag.value == 10) {  
            anonymousFlag.value = 20  
        } else {  
            anonymousFlag.value = 10  
        }  
    }  

    const content = ref('')  

    const send = async () => {  
        if (content.value == '') {  
            return uni.showToast({  
                title: '评论不能为空',  
                icon: 'none'  
            })  
        }  
        const res = await uni.showModal({  
            title: '是否发布评论?'  
        })  

        if (res.confirm) {  
            emits('confirm', content.value)  
            content.value = ''  
        }  
    }  

    const agreeRef = ref(null)  
    const agreeChange = () => {  
        if (!props.info.praiseFlag) {  
            emits('update:info', {  
                ...props.info,  
                ...{  
                    praiseFlag: true,  
                    praiseNum: (parseInt(props.info.praiseNum + 1))  
                }  
            })  
            agreeRef.value && agreeRef.value.setAgreeAnimation()  
        } else {  
            emits('update:info', {  
                ...props.info,  
                ...{ praiseFlag: false, praiseNum: (parseInt(props.info.praiseNum - 1)) }  
            })  
        }  
    }  

    const showSendBtn = ref(false)  

    const areaFocus = () => {  
        showSendBtn.value = true  
    }  

    const areaBlur = () => {  
        setTimeout(() => {  
            showSendBtn.value = false  
        }, 200)  
        inputBlur()  
    }  

    // 键盘聚焦模块  

    // bottom为键盘高度  bottom不为0时则键盘聚焦   
    const focusStyle = reactive({  
        position: 'fixed',  
        bottom: 0,  
        left: 0  
    })  

    const viewStyle = computed(() => {  
        return focusStyle.bottom != 0 ? focusStyle : {}  
    })  
    const keyboardHeightChange = (e) => {  
        focusStyle.bottom = e.detail.height + 'px'  
    }  

    const inputBlur = () => {  
        focusStyle.bottom = '0px'  
    }  
</script>  

<style scoped>  
    view {  
        box-sizing: border-box;  
    }  

    .input-wrap {  
        width: 750rpx;  
        height: 180rpx;  
        background: #FFFFFF;  
        box-shadow: 0rpx -7rpx 7rpx 0rpx rgba(0, 0, 0, 0.02);  
        padding: 21rpx 30rpx;  
        position: relative;  
        z-index: 33;  
    }  

    .qx-input {  
        display: flex;  
        flex-direction: row;  
        align-items: center;  
        box-sizing: border-box;  
        padding: 15rpx 21rpx;  
        background-color: #fff;  
    }  

    .qx-input-content {  
        flex: 1;  
        min-height: 44rpx;  
        max-height: 88rpx;  
        background: #F8FAFF;  
        border-radius: 7rpx;  
        border: 1rpx solid #DDE4F3;  
        font-size: 28rpx;  
        margin-left: 19rpx;  
        padding: 6rpx 21rpx;  
        color: #000;  
        line-height: 44rpx;  
    }  

    .qx-logo {  
        width: 39rpx;  
        height: 39rpx;  
    }  

    .niming {  
        font-size: 25rpx;  
        color: #222222;  
    }  

    .niming-logo {  
        margin-right: 11rpx;  
        width: 28rpx;  
        height: 28rpx;  
    }  

    .hide-box {  
        border: 1px solid #DDE4F3;  
        width: 28rpx;  
        height: 28rpx;  
        margin-right: 11rpx;  
        border-radius: 50%;  
    }  

    .un-niming {  
        border-radius: 50%;  
        border: 1px solid #DDE4F3;  
    }  

    /deep/ .placeholder-class {  
        font-size: 28rpx;  
        color: #A0A8CA;  
        line-height: 44rpx;  
    }  

    .options-box {  
        margin-left: 24rpx;  
    }  

    .options-box>text {  
        font-size: 21rpx;  
        color: #222222;  
    }  

    .size39 {  
        width: 39rpx;  
        height: 39rpx;  
    }  

    .share-btn {  
        opacity: 0;  
        z-index: 3;  
    }  

    .tips-texts {  
        height: 25rpx;  
        position: absolute;  
        right: 0;  
        bottom: 29rpx;  
        z-index: 3;  
        background: #FF584F;  
        border-radius: 12rpx;  
        padding: 0 9rpx;  
    }  

    .share-tips-text {  
        right: -12rpx;  
    }  

    .tips-texts>text {  
        font-size: 18rpx;  
        line-height: 25rpx;  
        color: #FFFFFF;  
    }  

    .send-logo {  
        margin-left: 21rpx;  
    }  

    .send-logo>image {  
        width: 52rpx;  
        height: 52rpx;  
    }  
</style>

操作步骤:

示例

预期结果:

键盘正常拉起 不会出现聚焦后立刻失焦的情况

实际结果:

textarea/input组件 ios端 第一次聚焦后自动失焦

bug描述:

通过监听textarea或input组件键盘高度事件 改变组件外层容器的样式:

当键盘高度大于0时 外层容器样式为固定定位 bottom值为键盘高度

问题:
在IOS端 textarea组件第一次聚焦后又立刻失焦 导致页面出现抖动
安卓无此问题

2025-07-02 10:10 负责人:无 分享
已邀请:
DCloud_UNI_JBB

DCloud_UNI_JBB

测试一下原生微信小程序iOS的表现是否一致

要回复问题请先登录注册