Как узнать, какая часть текста изменяется в поле ввода? - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть поле ввода, я надеюсь, что смогу определить детали того, что пользователь изменил.

Например:

  • Пользователь набрал «A», когда поле пусто:

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

  • Когда в поле есть «ABCD», пользователь ставит курсор после «C» и нажимает клавишу Backspace:

    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 голосов
/ 15 ноября 2018

После некоторой борьбы, я думаю, что вроде как разобрался ...

$('#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" />
0 голосов
/ 15 ноября 2018

EDIT Итак, это не работает при работе с середины ввода, но я бы предложил библиотеку разграничения строк, такую ​​как 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" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...