Skip to main content
  1. Blogs/
  2. 前端开发/

·152 words·1 min

以 vue directive 指令举例:

首先,对每个 input 输入框绑定 window 窗口变动事件:

Vue.directive("keyboard", {
  inserted: function (el) {
    const $input = el.querySelector("input");

    const onResize = () => {
    };

    const onFocus = () => {
      originalHeight = window.innerHeight;

      // 添加 resize 监听器
      window.addEventListener('resize', onResize);
    };

    const onBlur = () => {
      console.log('onblur')
      $input.removeEventListener('focus', $input._onFocus);
      window.removeEventListener('resize', $input._onResize);
    }
    $input.addEventListener('focus', onFocus);
    $input.addEventListener('blur', onBlur)

    // 存储事件处理函数用于卸载
    $input._onFocus = onFocus;
    $input._onResize = onResize;
  },
  unbind: function (el) {
    const $input = el.querySelector("input");
    // 移除事件监听器
    $input.removeEventListener('focus', $input._onFocus);
    window.removeEventListener('resize', $input._onResize);

    // 清除引用
    delete $input._onFocus;
    delete $input._onResize;
  }
});

判断键盘是否弹起(当前窗口小于初始化状态),通过 el.scrollIntoView 将当前输入框自动上升,避免遮挡。

const onResize = () => {
  console.log('onResize')
  const newHeight = window.innerHeight;

  // 判断是否是视口变小(可能是键盘弹出)
  if (newHeight < originalHeight - 50) {
    // 延迟一点再滚动,确保 DOM 更新完成
    setTimeout(() => {
      $input.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" });
    }, 50); // 可根据设备调整时间
  }
};

组件调用:

<van-field required v-keyboard v-model.trim="form.mobile" name="mobile" :rules="rules.mobile" maxlength="11"
  :border="false" :placeholder="$t('message.mobilePlaceholder')">
  <template #label>
	<span class="required">{{ $t("message.mobile") }}</span>
  </template>
</van-field>

实际效果: