vant@2项目中点击 input 弹出 ios 输入法导致的样式问题

236 阅读2分钟
大家好,我是 wiphone。

众所周知,在手机端 ios 和 android 的标准不一样,这会导致许多显示问题需要前端进行适配。

我今天就遇到了,记录它,希望能够帮助遇到同样问题的朋友。

开发场景:
项目顶部实现了一个检索弹层 dropdown-menu/dropdown-item,附带输入框。
这个弹层还有嵌套弹层 popup 用来选择科室。

问题描述:
1.在 dropdown-item 弹层点击输入框时,ios 弹出输入框,页面整体上移,弹层消失,只看得到遮罩层。
2.在 popup(底部弹出)弹层点击输入框时,ios 弹出输入框,页面整体不上移,被遮挡,只看得到遮罩层。

问题解决:

dropdown-item 部分:

弹层的 position 是 fixed,需要改用 absolute.
所以我们监听输入框 input 的焦距来改变。

html 部分:
<input style="width: 85%;height: 25px;padding: 5px 8px;border-radius: 8px;border: 1px solid #dadada;"
  v-model="doctorStr"
  placeholder="请输入完整姓名"
  @focus="doctorFocus"
  @blur="doctorBlur"
/>
vue 部分:
doctorFocus() {
  if (this.isIOS() && !this.IsWeChatDevTools()) {
    setTimeout(() => {
      // 获取className为van-dropdown-item__content的节点
      const dropdownMain = document.querySelector(
        ".van-dropdown-item__content"
      );
      if (dropdownMain) {
        // 设置position为fixed
        dropdownMain.style.position = "fixed";
        console.log("doctorFocus---", dropdownMain.style.position);
      }
    });
  }
},
doctorBlur() {
  if (this.isIOS() && !this.IsWeChatDevTools()) {
    setTimeout(() => {
      // 获取className为van-dropdown-item__content的节点
      const dropdownMain = document.querySelector(
        ".van-dropdown-item__content"
      );
      if (dropdownMain) {
        // 设置position为absolute
        dropdownMain.style.position = "absolute";
        console.log("doctorBlur---", dropdownMain.style.position);
      }
    });
  }
},

popup 部分:

需要为 popup 设置 id="officePopup"
弹层的 position 是 fixed,需要改用 absolute.
所以我们监听输入框 input 的值变化来改变。
并且需要设置滚动值。

html 部分:
<van-search
  @input="officeInputSearch"
  @blur="officeBlur"
  @cancel="searchOfficeList.length = 0"
  @clear="searchOfficeList.length = 0"
  v-model="officeStr"
  placeholder="请输入科室名"
  input-align="center"
/>
vue 部分:
officeInputSearch(e) {
  if (!e) {
    if (this.isIOS() && !this.IsWeChatDevTools()) {
      // 获取className为searchOffice的节点
      const officePop = document.getElementById("officePopup");
      setTimeout(() => {
        officePop.style.position = "fixed";
        officePop.style.top = "auto";
        console.log("officePop2---", officePop);
      });
    }

    // 如果搜索框为空,则显示所有科室
    this.searchStr = null;
    this.searchOfficeList.length = 0;
  } else {
    if (this.isIOS() && !this.IsWeChatDevTools()) {
      // 获取className为searchOffice的节点
      const officePop = document.getElementById("officePopup");
      const scrollTop =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop ||
        0;

      setTimeout(() => {
        officePop.style.position = "absolute";
        officePop.style.top = scrollTop + 115 + "px";
      });
    }

    // 实现你的实际业务代码
  }
},
基本上就是这样了,一些细节需要自己琢磨,感谢观看。