关于javascript:Js检测chrome-autofill

48次阅读

共计 1402 个字符,预计需要花费 4 分钟才能阅读完成。

背景

这几天遇到这么个需要,在输入框有值且鼠标悬浮的时候显示 clearable 按钮, 否则不显示。

需要自身并没有什么特地的,我的项目用的 vue2,只有在触发悬浮事件的时候检测绑定的值是否不为空即可。然而在 login 页面的时候却发现,页面初始加载之后,输入框里看似有值,然而绑定的 v -model 值却是空。

这理论就是浏览器主动填充的值 (字体大小不同,且有个蓝色背景)。

这个问题其实大家在开发中或多或少应该都遇到过,简略举几个栗子:

  1. 想去除主动填充的背景色
  2. 如下图一样悬浮 label 被遮挡
  3. 像我遇到的问题一样,看似有值理论获取不到

剖析

查阅了一些材料,失去了一些对于 autofill 的信息

  1. 各个浏览器对于 autofill 的实现并不相同,这里只以 chrome 为例
  2. 当主动填充产生时,chrome 并不会派发包含 change 事件在内的任何事件
  3. 因为没有事件的派发,所以也不可能通过 js 捕捉到 autofill 的事件
  4. 因为 autofill 是由浏览器管制而非实在用户触发,所以这不是个 isTrusted 的行为
  5. 因为这不是个 trusted 的行为,所以咱们不能通过 js 读取到 autofill 的值,直到实在用户动作

听起来有点绕,没关系,简略总结一下次要有两点:

  • chrome 主动填充的时候不会触发任何事件,所以 js 也捕获不到
  • 主动填充的值也不能被 js 取到

那么咱们就没方法检测到 autofill 了吗?
漏漏漏,其实答案就在眼前

解决办法

咱们能够看到主动填充的输入框里的款式变了,关上 F12,往下拉,就能够看到

好了,想解决主动填充背景色的敌人,能够用这个 css 笼罩这个伪类:
input:-internal-autofill-selected

接下来说一下在 js 里怎么解决这个问题

察看一下此处有个非凡的 css 属性 appearance,试验了一下 autofill 的状态,appearance 属性的值是 menulist-button。手动输出的时候 appearance 的值是 auto。
咱们能够利用这个属性来实现对 autofill 的检测

简略的写一个办法:

const detectAutofill = (element) => {return window.getComputedStyle(element, null).getPropertyValue('appearance') === 'menulist-button'
}

而后在页面初始化的时候加一个延时来调他, 试验了一下 600ms 左右根本能够调到,所以给个默认值提早 600ms

const detectAutofill = (element, timeout=600) => {
  return new Promise(resolve => {setTimeout(() => {resolve(window.getComputedStyle(element, null).getPropertyValue('appearance') === 'menulist-button')
    }, timeout)
  })
}

应用办法示例:

async testAutoFill () {this.autofilled = await detectAutofill(this.$refs.input)
}

参考资料:
https://dom.spec.whatwg.org/#…
https://kishoreconnect.com/ja…
https://medium.com/weekly-web…

正文完
 0