为了账号安全,请及时绑定邮箱和手机立即绑定

如何解决 chrome 自动完成与 vuetify 中的标签重叠的问题?

如何解决 chrome 自动完成与 vuetify 中的标签重叠的问题?

MYYA 2022-12-22 12:49:32
outlined尝试在 Vutify中创建带有文本字段的登录表单时,chrome 自动完成功能与labels,<v-text-field  v-model="email"  label="e-mail"  name="email"  outlined  prepend-icon="mdi-account"  type="text"  required></v-text-field>你可以在这里重新生成请填写并提交,然后返回。
查看完整描述

5 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

这就是我解决这个问题的方法。

看来我们的主要问题如下:

  • Chrome 的自动填充,在加载页面时,不会让界面做出反应,让设计像你的图像一样。

  • 所以在注入的时候,我们应该自己做一个修复,但是当登录名/密码被自动填充时,Chrome 没有任何事件可以通知我们。

有趣的是,浏览器窗口中的任何点击 FROM USER 都会自动通知反应性,并且一切正常,但 FROM 触发器/调度内部方式不起作用。

所以首先,我们需要找到一种在登录/密码自动填充后做出反应的方法。其次,我们需要自己修复设计,因为只有 FROM USER 操作才能使设计再次正常工作。

1.加载页面自动填充后反应

  • 就像 Harkness 提到的那样,我们可以尝试:-webkit-autofill在安装代码后的 X 秒内定期检查以查看是否注入了自动填充(从我的测试来看,Chrome/Firefox/Edge 工作正常)

  • 另一种解决方案是使用animationstart事件(参见此处:https ://github.com/material-components/material-components-web/issues/4447#issuecomment-580401216 )

我使用第一个解决方案:

export default {

  //...

  data() {

    return {

      //...

      autofillFix: false,

    }

  },

  //...

  mounted() {

    this.autoLoginCheckingInterface()

  },

  //...

  autoLoginCheckingInterface() {

    // each 100ms we check if the issue was produced

    let intervalDetectAutofill = setInterval(() => {

      if (

        // we target at least one of the stuff that will be affected by autofill

        // to do our checking

        document.querySelectorAll('input[type="password"]:-webkit-autofill')

          .length > 0

      ) {

        // and we inform the system about the issue if it is produced

        this.autofillFix = true


        // we stop to check if issue was produced

        clearInterval(intervalDetectAutofill)

      }

    }, 100)


    // if after 3s nothing appear, means no autofill was made

    setTimeout(() => {

      if (intervalDetectAutofill) {

        clearInterval(intervalDetectAutofill)

        intervalDetectAutofill = null

      }

    }, 3000)

  },

  //...

}

<!--

we will inject `.autofill-fix` class to be able fix design ourself at time of this bug occur

--> 

<v-text-field

      ...

      :class="{ 'autofill-fix': autofillFix }"

      ...

      label="Email address or username"

      ...

      dense

      outlined

      @focus="autofillFix = false"

/>

<!--

we use @focus to let the normal behavior take again the lead

because we know this USER ACTION will made Chrome work well again

-->

<v-text-field

      ...

      :class="{ 'autofill-fix': autofillFix }"

      ...

      label="Password"

      type="password"

      ...

      dense

      outlined

      @focus="autofillFix = false"

/>

2. 修正自己的设计

v-text-field我们可以看到填充时有什么变化。没有内容,我们可以看到:

//img1.sycdn.imooc.com//63a3e20e0001fec414630313.jpg

自动填充后,我们可以看到:

//img1.sycdn.imooc.com//63a3e219000195bd14760325.jpg

所以从红色部分,我们可以看到需要在存在时注入以下代码以.autofill-fix正确的方式修复设计


.autofill-fix.v-text-field--outlined.v-input--dense .v-label {

  left: -28px!important;

  transform: translateY(-16px) scale(.75);

}

注意:如果不使用outlinedor ,则需要更改 CSS 选择器dense。注意选择器https://specificity.keegan.st/的特异性。事实上,您需要使固定更改适应您的设计


查看完整回答
反对 回复 2022-12-22
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

我相信我已经用非常通用的几行代码取得了很好的结果。


 mounted() {

    setTimeout(() => {

      const els = document.querySelectorAll("input:-webkit-autofill")

      els.forEach((el) => {

        const label = el.parentElement.querySelector("label")

        label.classList.add("v-label--active")

      })

    }, 500)

  },

如果浏览器自动填充 v-text-field,此代码会将“active”类添加到 Label。v-text-field 的行为没有变化。


查看完整回答
反对 回复 2022-12-22
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

另一种方法是像@elazard在这里建议这样定义一个自动填充变量


data () {

        return {

            login: null,

            password: null,

            autofill: false,

            intervalDetectAutofill: null

        }

    },

<v-text-field

    v-model="password"

    type="password"

    label="Password"

    :placeholder="autofill ? ` ` : null"

/>

使用@adam-reis 给出的解决方案mounted(),在登录页面的


mounted () {

        // search for autofill every 100ms

        this.intervalDetectAutofill = setInterval(() => {

            if (document.querySelectorAll("input[type=\"password\"]:-webkit-autofill").length > 0) {

                this.autofill = true

            }

        }, 100)


        // clean interval if needed after 3s

        setTimeout(() => {

            if (this.intervalDetectAutofill) {

                clearInterval(this.intervalDetectAutofill)

                this.intervalDetectAutofill = null

            }

        }, 3000)

    },

当然,如果用户输入,则将自动填充设置为 false


watch: {

        password () {

            this.autofill = false

        },

        autofill () {

            // clean interval if autofill detected or user input

            if (this.intervalDetectAutofill) {

                clearInterval(this.intervalDetectAutofill)

                this.intervalDetectAutofill = null

            }

        }

    },


查看完整回答
反对 回复 2022-12-22
?
智慧大石

TA贡献1946条经验 获得超3个赞

好的,所以我所做的是这样的:


在输入


:placeholder="!autofilled ? ' ' : ''"

在脚本中


data() {

        return {

            form: {

                email: '',

                password: '',

            },

            error: null,

            autofilled: false,

        };

},

watch: {

    'form.email'() {

        this.autofilled = true;

     },

},

它的作用:基本上将占位符设置为一个空格总是“提升”标签。不幸的是,静态设置它会使标签无法返回,即使您在填充后清空输入。所以我所做的是使占位符动态化,并且在该占位符恢复为空后对输入进行任何更改之前仅将其设置为空白。它并不完美,因为在用户保存密码之前的初始加载时,标签会被提升,但我还没有发现比这更好的东西。


查看完整回答
反对 回复 2022-12-22
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

浏览器上的自动填充功能通常通过直接设置相关字段的值来工作。在这种情况下,字段的标签仅在输入字段获得焦点时才移开,而在与字段中的值模糊时则远离。在自动填充的情况下,不会触发焦点事件,因此标签会保留在原处。

要解决此问题,您必须(或让某人)在 Vuetify 中进行更改。


查看完整回答
反对 回复 2022-12-22
  • 5 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信