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
我们可以看到填充时有什么变化。没有内容,我们可以看到:
自动填充后,我们可以看到:
所以从红色部分,我们可以看到需要在存在时注入以下代码以.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/的特异性。事实上,您需要使固定更改适应您的设计
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 的行为没有变化。
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
}
}
},
TA贡献1946条经验 获得超3个赞
好的,所以我所做的是这样的:
在输入
:placeholder="!autofilled ? ' ' : ''"
在脚本中
data() {
return {
form: {
email: '',
password: '',
},
error: null,
autofilled: false,
};
},
watch: {
'form.email'() {
this.autofilled = true;
},
},
它的作用:基本上将占位符设置为一个空格总是“提升”标签。不幸的是,静态设置它会使标签无法返回,即使您在填充后清空输入。所以我所做的是使占位符动态化,并且在该占位符恢复为空后对输入进行任何更改之前仅将其设置为空白。它并不完美,因为在用户保存密码之前的初始加载时,标签会被提升,但我还没有发现比这更好的东西。
TA贡献1846条经验 获得超7个赞
浏览器上的自动填充功能通常通过直接设置相关字段的值来工作。在这种情况下,字段的标签仅在输入字段获得焦点时才移开,而在与字段中的值模糊时则远离。在自动填充的情况下,不会触发焦点事件,因此标签会保留在原处。
要解决此问题,您必须(或让某人)在 Vuetify 中进行更改。
添加回答
举报