javascript - 通过js将新添加的字符获取到输入中

标签 javascript jquery input

我知道这似乎是一个很容易的目标。我有一个 input[type=text],我想检测其中新添加的字符。正常的方式是:

$selector.keypress(function(e) {
    //do sth here
    var newchar = String.fromCharCode(e.which);
});

但上述方法在 android 设备上的某些浏览器 上无法正常工作。键入 android 虚拟键盘不会触发 keypress

然后我发现下面的方法比较好:

$selector.on('input', function(e){
    //do sth here
});

它适用于 android 设备,而且它可以检测 cut/paste

现在的问题是,有没有办法知道 input 中新添加的字符?每次输入时是否需要进行复杂的字符串比较,即比较输入框中的前一个字符串和新字符串?我说这很复杂,因为你可能并不总是在最后输入 char(s),你可能会在前一个字符串的中间插入一些 char(s)。想一想,输入框之前的字符串是"abc",粘贴后新的字符串是"abcxabc",怎么知道新粘贴的字符串是< strong>“abcx”,还是“xabc”

按键的方法很简单:

String.fromCharCode(e.which);

那么,on('input') 方法是否有类似的方法来做到这一点?


在看完 Yeldar Kurmangaliyev 的回答后,我深入研究了这个问题,发现这确实比我之前的预期要复杂。这里的关键点是,有一种方法可以通过调用获取光标位置:selectionEnd

正如 Yeldar Kurmangaliyev 提到的,他的回答无法涵盖情况:

it is not working is when you select text and paste another text with replacing the original one.

根据他的回答,我修改了getInputedString函数如下:

    function getInputedString(prev, curr, selEnd) {
        if (selEnd === 0) {
          return "";
        }
        //note: substr(start,length) and substring(start,end) are different
        var preLen = prev.length;
        var curLen = curr.length;
        var index = (preLen > selEnd) ? selEnd : preLen;
        var subStrPrev;
        var subStrCurr;
        for(i=index; i > 0; i--){
            subStrPrev = prev.substr(0, i);
            subStrCurr = curr.substr(0, i);
            if (subStrCurr === subStrPrev) {
                var subInterval = selEnd - i;
                var interval = curLen - preLen;
                if (interval>subInterval) {
                    return curr.substring(i, selEnd+(interval-subInterval));
                }
                else{
                    return curr.substring(i, selEnd);
                }

            }
        }

        return curr.substring(0, selEnd);
    }

代码是 self 解释。核心思想是,无论添加什么字符(键入或粘贴),新内容都必须在光标位置结束。

我的代码也有一个问题,例如当prev是abcabc|时,你全选,然后粘贴abc,我的代码返回值为""。实际上,我认为这是合理的,因为对于我的场景,我认为这与从以前的 abcabc| 中删除 abc 是一样的。

此外,我将 on('input') 事件更改为 on('keyup'),原因是,对于某些 android 浏览器, this.selectionEnd 将不会以相同的方式工作,例如,以前的文本是 abc|,现在我粘贴 de,当前字符串将是 abcde|,但是根据不同的浏览器,on('input')里面的this.selectionEnd可能是3,或 5。即有些浏览器会在添加输入之前报告光标位置,有些浏览器会在添加输入后报告光标位置。

最终,我发现 on('keyup') 对于我测试的所有浏览器都以相同的方式工作。

整个demo如下:

DEMO ON JSFIDDLE

处理跨浏览器兼容性总是很困难,尤其是当您需要考虑触摸屏时。希望这可以帮助某人,并玩得开心。

最佳答案

重要提示:

  • 当用户输入一个字符时,光标会停留在它后面
  • 当用户粘贴文本时,光标也位于粘贴文本之后

假设这样,我们可以尝试建议输入的\粘贴的字符串。

例如,当我们有一个字符串 abc 并且它变成了 abcx|abc (| 是一个游标)——我们知道实际上他粘贴了“abcx”,但没有粘贴“xabc”。

算法如何做到这一点?假设我们有之前的输入 abc 和当前的输入:abcx|abc(光标在 x 之后)。

新的长度为7,而之前的长度为4。这意味着用户输入了4个字符。只需返回这四个字符 :)

唯一不起作用的情况是当您选择文本并粘贴另一个文本以替换原始文本时。我相信您自己会想出一个解决方案 :) 这是工作片段:

function getInputedString(prev, curr, selEnd) {
  if (prev.length > curr.length) {
    console.log("User has removed \ cut character(s)");
    return "";
  }

  var lengthOfPasted = curr.length - prev.length;
  if (curr.substr(0, selEnd - lengthOfPasted) + curr.substr(selEnd) === prev)
  {  
      return curr.substr(selEnd - lengthOfPasted, lengthOfPasted);
  } else {
      console.log("The user has replaced a selection :(");
      return "n\\a";
  }
}

var prevText = "";

$("input").on('input', function() {
  var lastInput = getInputedString(prevText, this.value, this.selectionEnd);
  prevText = this.value;

  $("#result").text("Last input: " + lastInput);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
<div id="result">Start inputing...</div>

关于javascript - 通过js将新添加的字符获取到输入中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34216524/

相关文章:

javascript - 如何让用户通过点击添加另一个上传输入?

javascript - noUiSlider 链接错误

C : Input file does not sort in array

javascript - Document API 何时引入方法

javascript - 使用ajax设置PHP session 变量

foreach 循环内的 Javascript .match 和 .test

javascript - 使用 Uniform/jquery 更改 SELECT 的高度

c - 为什么我的 scanf 不能正常工作,而当我移动它时,它工作正常?

javascript - 检查 javascript 中是否存在变量;不起作用

javascript - 为什么<Table/>多次渲染时不显示复选框?