【问题标题】:How can I get the NEW value of an HTML text input during a keypress event via jQuery?如何通过 jQuery 在按键事件期间获取 HTML 文本输入的新值?
【发布时间】:2011-03-28 16:05:39
【问题描述】:

我只能在没有新按键的情况下检索值。使用keyup 事件不是一个选项,因为如果用户不释放密钥,它不会触发。这很重要,因为我想对每一个按键都采取行动。

也不可接受将旧值与可从事件参数访问的 keyCode 组合,因为不能保证用户会在文本框中键入到字符串的末尾。

【问题讨论】:

  • 在输入字段上使用change事件怎么样?
  • 更改事件仅在输入字段失去焦点时才会发生,因此无法正常工作..
  • 在使用 Bacon.js 之后,我会完全用它来解决这个问题

标签: javascript html jquery keypress jquery-events


【解决方案1】:

将您的处理程序代码包装在 setTimeout(function() { ... }, 0) 中。

这将在value 更新后执行下一个消息循环中的代码。

【讨论】:

  • 但是那样我就会失去阻止事件的机会。但是,如果我将此与 Jeff T 的建议结合起来,如果我发现它无效,我可以将输入的值回滚到之前的状态。不过,我仍然对其他想法持开放态度。
  • 如果希望能够回滚到之前的状态,可以在进入setTimeout之前保存该值,发现需要回滚时再参考。在这里更新了 jsFiddle:jsfiddle.net/3tRMx/1 尝试输入 'xx' 以查看工作中的回滚。
  • @Ender:我修改了你的代码并发现了一个有趣的问题:如果你连续按下一个键足够长的时间,一些键最终会“退出”,所以不管它们应该被删除,它们都会出现在下一个消息循环中。我猜这是因为下一个按键事件发生在上一个按键的 setTimeout 回调之前。相关示例:jsfiddle.net/vrjAA(按住字母“i”一段时间)
  • @kahoon - 哈!你是对的。经过一番思考,我想出了一些我认为可以解决问题的方法。将 oldVal 转换为全局(或至少半全局)变量,并在 keydown 事件中更新它,而不是在按键开始时更新它。使用这个,我按住一个键至少一分钟,没有“逃脱者”。在这里修改了你的 jsFiddle:jsfiddle.net/vrjAA/1
【解决方案2】:

可以计算出按键后的值。在非 IE 浏览器中这很容易,而在 IE 中则比较棘手,但以下方法可以做到:

document.getElementById("your_input").onkeypress = function(evt) {
    var val = this.value;
    evt = evt || window.event;
    var charCode = typeof evt.which == "number" ? evt.which : evt.keyCode;
    if (charCode) {
        var keyChar = String.fromCharCode(charCode);
        var start, end;
        if (typeof this.selectionStart == "number" && typeof this.selectionEnd == "number") {
            start = this.selectionStart;
            end = this.selectionEnd;
        } else if (document.selection && document.selection.createRange) {
            // For IE up to version 8
            var selectionRange = document.selection.createRange();
            var textInputRange = this.createTextRange();
            var precedingRange = this.createTextRange();
            var bookmark = selectionRange.getBookmark();
            textInputRange.moveToBookmark(bookmark);
            precedingRange.setEndPoint("EndToStart", textInputRange);
            start = precedingRange.text.length;
            end = start + selectionRange.text.length;
        }
        var newValue = val.slice(0, start) + keyChar + val.slice(end);
        alert(newValue);
    }
};

【讨论】:

  • 谢谢,这是最接近我想要实现的目标。但一个主要问题是:它仍然不能防止将任意数据复制和粘贴到输入中。
  • 好的。你没有在问题中提到这一点。在大多数浏览器中,您可以使用简单的document.getElementById("your_input").onpaste = function() { return false; }; 来防止这种情况发生。 Firefox 2 和我认为所有版本的 Opera 都不支持粘贴事件。
  • 不错。我对所有人稍作修改,将其设置为独立函数,将事件作为参数并返回预期的新值,但我猜 stackoverflow 不会让我将其粘贴到此处。 . .
  • @RobertMacGrogan:您可以从 cmets 链接到 jsFiddle 或类似内容。
【解决方案3】:

这是一个可行的想法。使用 keypress 并在该点存储 val,以便您始终可以将当前值与最后一个值进行比较,并找出字符串中的差异。不同之处在于按下的键。

执行此操作的一种方法是将字符串转换为数组并像在此处那样比较两个数组:JavaScript array difference

从未尝试过这样的事情,所以它可能不可行,但可能值得一试。

【讨论】:

    【解决方案4】:

    我有一个 TAB 键的特殊情况,它改变了 keyUp 中的 e.target,所以这就是解决方案 - 绑定到容器元素,在 keyDown 处理程序中获取目标输入,订阅 keyUp 并读取值。

    $("#container").keydown(function (e) {
       //here you decide whether to handle the key event, and grab the control that sent the event 
       var myInput = e.target;
       $("#container").one('keyup', function() {
          console.log(myInput.val());  
          // do smth here
       });
    });
    

    【讨论】:

      猜你喜欢
      • 2012-10-27
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      • 2016-05-15
      • 1970-01-01
      相关资源
      最近更新 更多