一、问题描述:

        以chrome浏览器为例,用户可以通过设置,存储当前页面账号的登录信息,再次访问该页面时浏览器会自动填充账号信息(仅限https),避免手动输入用户名和密码。但最近在开发过程中发现,浏览器自动填充账号密码后,并没有触发前端代码中的onchang事件,需要手动点击页面中任意的一个地方,onchange事件才会执行,才能取到浏览器自动填充的账号和密码相应的值。这就导致在首次加载完成后,如果用户和页面并没有发生任何交互时(点击,滚动不算),登陆框中虽然有用户名和密码,但登陆按钮是置灰不能点击的。

        该问题是由于chrome浏览器的安全机制所导致的。

二、问题排查过程

        在开发时,首先尝试在useEffect、useLayoutEffect、window.onload等钩子或事件中获取填充后的值;然后又尝试在事件中去添加setTimeout;最后,在onload结束中,尝试在代码里模拟鼠标触发一次点击事件,结果。。。都不行。

window.onload = ()=>{
    setTimeout(function() {
        document.getElementById('myElement').click();
    }, 1000);
}

        然后就开始找各个大厂的登陆页面,想看看他们是否遇到并解决了这个问题,结果发现jing东的登陆页面居然可以,于是就看了一下他们的源码:

三、解决方案

        在找到了最关键的那段代码后:垂死病中惊坐起!

        因为浏览器在自动填充账号密码后,会给input框追加一个伪类,所以他们的实现逻辑是在页面加载完成,并延迟1秒后,去判断当前的密码框是否被浏览器追添加了伪类‘-webkit-autofill’,如果密码框存在该类名,说明浏览器已经自动填充当前登陆页的账号、密码,此时就可以改变登陆按钮的状态!

useEffect(() => {
    setTimeout(() => {
      const ele1 = document.querySelector('#accountName')
      const ele2 = document.querySelector(':-webkit-autofill')
      if (ele1 === ele2) {
        setIsButtonDisabled(false)
      }
    }, 1000);
  }, [])

注意:延时时间不要设置为小于一秒,因经测试,设置500毫秒、800毫秒时ele2是取不到dom的。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐