如何实现输入密码提示大写锁定键

4,728 阅读3分钟

登录框

输入密码时提示大写锁定键,尤其是在密码有输入次数限制时显得人性化,那么是怎么实现的呢?

代码实现

实现方法是以 vue + elementUI 作为例子,但用在其它地方也差不多一样。

实现一


大致思路:在密码框输入时才进行判断,过滤掉同时按住shift键和字母键的情况,并且密码框失去焦点后就不显示提示。

完整代码

<template>
  <div>
    <el-input 
     type="password" 
     v-model.trim="userPassword"  
     placeholder="请输入密码" 
     @keyup.native="onkeyup" 
     @keydown.native="onkeydown"
     @blur="bigChar=false">
    </el-input>
    <el-tag v-show="bigChar" type="warning">大写锁定已打开</el-tag>
  </div>
</template>
<script>
export default {
  data () {
    return {
      userPassword: '',
      bigChar: false,
      shifKey: undefined
    }
  },
  methods: {
    onkeyup (event) {
      const _that = this
      // 判断是否按键为caps Lock
      if (event.keyCode === 20) {
        _that.bigChar = !_that.bigChar
        return
      }
      // 按键不是caps Lock,判断每次最后输入的字母的大小写
      let e = event || window.event  
      let keyvalue = e.keyCode ? e.keyCode : e.which
      let shifKey = this.shifKey
      if (typeof (_that.userPassword) === 'undefined') return
      let userPassword = _that.userPassword
      let strlen = userPassword.length

      if (strlen) {
        let uniCode = userPassword.charCodeAt(strlen - 1)
        // 65到90字母键
        if (keyvalue >= 65 && keyvalue <= 90) {
          // 是否同时按住shift键
          if (((uniCode >= 65 && uniCode <= 90) && !shifKey) || ((uniCode >= 97 && uniCode <= 122) && shifKey)) {
            _that.bigChar = true
          } else {
            _that.bigChar = false
          }
        }
      }
    },
    onkeydown (event) {
      let e = event || window.event
      let keyvalue = e.keyCode ? e.keyCode : e.which
      let shifKey = e.shiftKey ? e.shiftKey : ((keyvalue === 16))
      this.shifKey = shifKey
    }
  }
}
</script>

但这并不是完美的实现方式,在密码框未获取焦点前按下caps Lock键亮灯,再点击密码框不输入,按下caps Lock键,会显示大写提示。这就不是我们想要的效果了。

实现二


根据实现一出现的问题,我们有了实现二。在实现一的基础,当密码框未获取焦点时,加个事件监听大写锁定键,用isFocusPW来判断是否聚焦显示。

完整代码

<template>
  <div>
    <el-input 
     type="password" 
     v-model.trim="userPassword"  
     placeholder="请输入密码" 
     @keyup.native="onkeyup" 
     @keydown.native="onkeydown"
     @blur="isFocusPW=false" 
     @focus="isFocusPW=true">
    </el-input>
    <template v-if="isFocusPW">
      <el-tag v-show="bigChar" type="warning">大写锁定已打开</el-tag>
    </template>
  </div>
</template>
<script>
export default {
  data () {
    return {
      userPassword: '',
      bigChar: false,
      shifKey: undefined,
      isFocusPW: false
    }
  },
  mounted () {
    window.addEventListener('keydown', (event) => {
      let e = event || window.event
      //  检测大写锁定键
      if (e.keyCode === 20) {
        if (!this.isFocusPW) {
          this.bigChar = !this.bigChar
        }
      }
    })
  }
  methods: {
    onkeyup (event) {
      const _that = this
      // 判断是否按键为caps Lock
      if (event.keyCode === 20) {
        _that.bigChar = !_that.bigChar
        return
      }
      // 按键不是caps Lock,判断每次最后输入的字母的大小写
      let e = event || window.event 
      let keyvalue = e.keyCode ? e.keyCode : e.which
      let shifKey = _that.shifKey
      if (typeof (_that.userPassword) === 'undefined') return
      let userPassword = _that.userPassword
      let strlen = userPassword.length

      if (strlen) {
        let uniCode = userPassword.charCodeAt(strlen - 1)
        // 65到90字母键
        if (keyvalue >= 65 && keyvalue <= 90) {
          // 是否同时按住shift键
          if (((uniCode >= 65 && uniCode <= 90) && !shifKey) || ((uniCode >= 97 && uniCode <= 122) && shifKey)) {
            _that.bigChar = true
          } else {
            _that.bigChar = false
          }
        }
      }
    },
    onkeydown (event) {
      let e = event || window.event
      let keyvalue = e.keyCode ? e.keyCode : e.which
      let shifKey = e.shiftKey ? e.shiftKey : ((keyvalue === 16))
      this.shifKey = shifKey
    }
  }
}
</script>

但是如果是浏览器之外或其它标签页按下的大写锁定键,是没有监听到的,还是会出现实现一出现的问题,不过我认为可以不考虑,这样就可以了。

总结

一开始做这个功能以为会很好实现,结果写着写着代码越写越多了:joy:。难怪现在输入密码都很少有这类提示了。