我怎么知道在输入框中更改了文本的哪一部分?

时间:2018-11-15 03:39:31

标签: javascript jquery html input

我有一个输入框,希望我能检测到用户修改内容的详细信息。

例如:

  • 在框为空的情况下,用户键入“ A”:

      

    deletedTextCount = 0, deletePosition = -1, insertPosition = 0, insertedText = 'A'

  • 当“ ABCD”位于框中时,用户将插入号放在“ C”之后并按退格键:

      

    deletedTextCount = 1, deletePosition = 2, insertPosition = -1, insertedText = ''

  • 当“ ABCD”位于框中时,用户选择“ BC”并粘贴“ FOO”:

      

    deletedTextCount = 2, deletePosition = 1, insertPosition = 1, insertedText = 'FOO'

输入事件的属性是否可以提供这些,或者我必须以某种方式计算出这些?

$('#input').on('input', onChange);

let before = '';

function onChange(target){
  const { value: after } = target.currentTarget;
  
  console.log(`before: ${before}, after: ${after}`);
  
  let insertedText = '';
  let insertPosition = -1;
  
  let deletedTextCount = 0;
  let deletePosition = -1;
  
  before = after;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input" type="text" />

2 个答案:

答案 0 :(得分:0)

编辑 好的,所以从输入的中间开始工作时不起作用,但是我建议使用jsdiff之类的字符串区分库来获得非常详细的更改列表。


此功能将找出更改,添加或删除的内容。

$('#input').on('input', onChange);

let before = '';

function onChange(target){
  const { value: after } = target.currentTarget;
  // Length of change, negative if removed
  const lengthChange = after.length - before.length;
  let changed;
  // If added some, get the new stuff
  if (lengthChange > 0) {
    changed = after.slice(after.length - lengthChange);
  // Other wise get the old stuff
  } else {
    changed = "-" + before.slice(before.length + lengthChange);
  }
  console.log(`before: ${before}, change: ${changed}, after: ${after}`);
  before = after;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input" type="text" />

答案 1 :(得分:0)

经过一番挣扎,我认为我已经解决了...

$('#input').on('input', onChange);

let before = '';

function onChange(target){
    const { selectionStart: start, value: after } = target.currentTarget;
    
    // calculate the different starting points from both direction
    let p1 = 0, p2 = 0;
    // calclate the end point first
    for(; p2 < after.length - start; p2++){
        if(before[before.length - 1 - p2] === undefined || before[before.length - 1 - p2] !== after[after.length - 1 - p2]){
            break;
        }
    }
    // calclate start point
    for(; p1 < after.length - p2 - (after.length > before.length ? 1 : 0); p1++){
        if(before[p1] !== after[p1] || p1 + p2 >= before.length){
            break;
        }
    }
    
    let insertedText = '';
    let insertPosition = -1;
    
    let deletedTextCount = 0;
    let deletePosition = -1;
    
    // has delete
    if(p1 + p2 < before.length){
        deletedTextCount = before.length - (p1 + p2);
        deletePosition = p1;
    }

    // has add
    if(p1 + p2 < after.length){
        insertedText = after.substr(p1, after.length - (p1 + p2));
        insertPosition = p1;
    }
    
    console.log(`deletePosition: ${deletePosition}, deletedTextCount: ${deletedTextCount}, insertPosition: ${insertPosition}, insertedText: "${insertedText}"`);
    
    before = after;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input" type="text" />