这个问题困扰了我1个周,走了很多弯路,总算解决。。。

问题描述:

开发中,会出现超长表单的情况。

而一般我们的‘提交’按钮都是在底部或者顶部悬挂。

这时就会出现一个问题:当我们点击提交时,校验失败的表单元素不在可视范围,点击没有反应的情况。

如果能直接移到第一个校验失败的表单元素处,即是最棒的体验。

******************************思路整理(觉得啰嗦直接跳至解决问题)*******************************

 思路一:校验失败时 触发focus,这样有一个不好的体验,每次都会触发键盘的弹起,即使setTimeout 隐藏键盘 uni.hideKeyboard(); 还是会闪一下。这个问题是无解。(有好办法请留言,万分感谢)

思路二:获取dom,调用scrollIntoView.  vue3.2  的ref ,无法取到dom . 后发现uni.createSelectorQuery().selectAll()可以获取dom元素的大小,位置的属性,但在组件内部怎么都取不到,一直返回null,这个问题解决方案详见https://blog.csdn.net/guyywan_1314/article/details/128419304

**************************************解决问题**************************************

我的表单元素是动态渲染,这里给组件加上class, wechat dev tool 可见dom结构。先上代码。

<crm-form-item
      class="crm-form-item"
      v-for="(field, index) in crmForm.crmFormFields || []"
      :key="field.fieldId + index"
      :item="field"
      :initValue="field.initValue"
      :ref="setColumnRefs"
      v-model:dialogValue="formValues"
      @update="updateValue"
    >

let columnRefTops: any[] = [];

 nextTick(() => {
      const query = uni.createSelectorQuery().selectAll('.crm-form-item');
      query
        .boundingClientRect((res: any) => {
          columnRefTops = res.map((item) => item.top);
        })
        .exec();
    });

uni.pageScrollTo({
            scrollTop: columnRefTops[index],
            duration: 100,
          });

 表单请求返回后,保存所有表单元素组件.crm-form-item的top值到数组。 点击提交时遍历所有元素组件的校验方法,如遇校验失败,根据遍历索引,可以取到其top值。 
Perfect!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐