【问题标题】:Change event input character更改事件输入字符
【发布时间】:2013-02-13 10:41:41
【问题描述】:

是否可以通过更改某些event 对象属性来简单地更改写入文本字段中的字符?例如,我想隐藏命令中的密码字符:
用户类型:

登录用户名密码

我想出现:

登录用户名********

并将密码保存到变量中。所以,一旦textbox.value 包含/^login [a-zA-Z0-9]+ /,我想将任何键重新映射到*

编辑 - 尊敬的 cmets 谈到误解了我的问题:
因为以上都发生在一个小命令行客户端中,并且可能有多个命令,我可能想通过* 混淆来保护,所以没有使用<input type="password" /> 的想法是可以接受的!

【问题讨论】:

  • 你有什么理由不使用<input type="password" />
  • 假设您在 html 上使用 JS,您可以只使用密码字段吗?
  • 伙计,我想如果我写login username password 就足够明显了,我们在谈论命令行!
  • 不,这绝对不明显。您提到文本字段。那会是命令行吗?
  • @TomášZato 我已经为你建立了一个fiddle。它并不完美,但可以使用 一个 已知命令(如 login)来完成这项工作。 FF和BACKSPACE也有问题,但也许你可以进一步开发代码。

标签: javascript keypress keyevent


【解决方案1】:

这个 sn-p 可以解决问题。它并不完美,但可以进一步发展。

window.onload = function () {
    var cmdfield = document.getElementById('cmdfield'),
        commandString = '',
        cmds = '(login|logout)',
        rex = new RegExp('^' + cmds + ' [a-zA-Z0-9]+ (\\w*)'),
        keyPress = function (e) {       
            if ((e.which > 64 && e.which < 123) || (e.which > 47 && e.which < 58) || e.which === 32) {
                commandString += String.fromCharCode(e.which);
                this.value = commandString.replace(rex, function (m, a, b) {
                    var command = m.split(' ')[0],
                        param = m.split(' ')[1],
                        len = b.length;
                    if (len > 0) {
                        return command + ' ' + param + ' ' + new Array(len + 1).join('*');
                    }
                    if (len === 0) {
                        return command + ' ' + param + ' ';
                    }
                });
            }
            e.preventDefault();
            return;
        },
        keyDown = function (e) {
            if (e.which === 8) {
                commandString = commandString.substring(0, commandString.length - 1);
                e.stopPropagation();
                return;
            }
            if (!((e.which > 64 && e.which < 122) || (e.which > 47 && e.which < 58) || e.which === 32)) {
                e.preventDefault();
            }
            return;
        };
    cmdfield.addEventListener('keydown', keyDown, false);
    cmdfield.addEventListener('keypress', keyPress, false);
}

cmds 是一个以竖线分隔的所有单词列表,它后面应该有一个可见参数,并且在该参数之后,文本字段上会有星号,直到下一个空格。如果命令不在列表中,则不会混淆第三个参数。

如果您想在同一行中检测多个此类组合,只需使用下面的正则表达式:

rex = new RegExp('\\b' + cmd + ' [a-zA-Z0-9]+ (\\w*)', 'g'),

“命令文本”的真实值存储在commandString中。

请注意,此实现不受鼠标或剪贴板文本编辑的保护。此外,在 Firefox 上运行时,BACKSPACE 不会在用户再次开始写入之前清空该字段。

jsFiddle 的现场演示。


编辑

实际上,您的问题是关于覆盖 Event 对象属性。一般来说,这些属性是只读的,不能修改。但是,该规则似乎有一个例外:至少 IE9 允许在 onkeypress 处理程序中修改 window.event.keyCode。下面的 sn-p 在调用内联 onkeypress=capitalize() 时在 IE9 中确实有效,但不适用于 addEventListener() 附加的处理程序。

function capitalize() {
    key = window.event.keyCode;
    if (key > 96 && key < 123) {
        window.event.keyCode = window.event.keyCode - 32;
    }
    return window.event.keyCode;
}

【讨论】:

  • 非常感谢,这将激励我。
  • 我接受了这一点,尽管这不是我的问题的答案 - 如何更改实际按下的字符。我相信这不是直接可能的,尽管可以由window.dispatchEvent() 完成。
  • 我已经看到只能在 IE 和onkeypress 中工作,恐怕这是唯一的跨浏览器方式。 Here's 代码问题,适用于 IE。
  • 它肯定只能与 onkeypress 一起使用,但事实上只有在 IE 中,密钥 ID 不是只读的,这对我来说是个坏消息。
  • @TomášZato 我在回答中添加了一些关于 IE 中只读问题的信息。
【解决方案2】:

您可以使用input type=password,但出于任何其他原因,以下脚本将为您完成这项工作。

var field = document.getElementById("password")
var val= "";
field.onkeydown = function(evt){
    val+= String.fromCharCode(evt.keyCode)      
    this.value = val.replace(/./g,"*");      
   document.getElementById("hiddenfieldPassword").value = val; // Hidden Field to store the password.
  return false;   
}

【讨论】:

  • 用箭头键和其他非字符键试试这个。用 SHIFT 试试这个 - 大小写将被忽略。最后,不要忘记输入的命令不能消失
  • 我做了一些 JS fiddle 来告诉你,你的代码并不能真正工作 - jsfiddle.net/vS2ZX/1
猜你喜欢
  • 2012-09-16
  • 1970-01-01
  • 2019-03-31
  • 2019-12-28
  • 2014-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多