粘贴时如何根据正则表达式验证字段输入?

How can I validate field input against a regex when pasting?

我想用正则表达式验证输入字段(替换所有元音)。 输入应始终与该正则表达式匹配,无论是输入还是粘贴到该字段。

我知道如何处理打字部分,但我需要复制粘贴方面的帮助。 应跳过所有元音 (e.g.: "abcde" copy --> "bcd" paste)

    $('document').ready(function(){
      var pattern = /[aeiou]/ig;

      $("#input").on("keypress keydown", function (e) {
        if (e.key.match(pattern) !== null) {
          e.preventDefault();
        }
      });
      
      $("#input").on("paste", function (e) {
        var text = e.originalEvent.clipboardData.getData('Text');
        e.preventDefault();

        //TODO... replace all vowels
        console.log(text);
      });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' id='input'/>

起初我试图替换它们,只是用 $('#input').val($('#input').val() + copiedValue) 设置值,但这只有在光标位于输入的末尾时才有效。

一种方法是从 paste 事件中操纵文本字段的值:

$('document').ready(function(){
      var pattern = /[aeiou]/ig;

      $("#input").on("keypress keydown", function (e) {
        if (e.key.length == 1 && !e.ctrlKey && !e.altKey && e.key.match(pattern) !== null) {
          e.preventDefault()
        }
      });
      
      $("#input").on("paste", function (e) {
        var text = e.originalEvent.clipboardData.getData('Text').replace(pattern, "");
        e.preventDefault();
        let input = e.originalEvent.target,
            start = input.selectionStart,
            end = input.selectionEnd;
        input.value = input.value.substr(0, start) + text + input.value.substr(end);
        input.selectionStart = start + text.length;
        input.selectionEnd = input.selectionStart;
        //TODO... replace all vowels
        console.log(text, input.value);
      });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' id='input'/>

一站式解决方案订阅了 input 事件。除了清理任务之外,处理程序还必须负责重新建立输入字段的确切或最预期的 cursor/caret 位置,以免破坏用户体验...

function getSanitizedValue(value) {
  return value.replace(/[aeiou]/ig, '');
}

function handleInput(evt) {
  evt.preventDefault();

  const elmNode = evt.currentTarget;

  const currentValue = elmNode.value;
  const sanitizedValue = getSanitizedValue(currentValue);

  if (currentValue !== sanitizedValue) {
    const diff = sanitizedValue.length - currentValue.length;
    const { selectionStart, selectionEnd } = elmNode;

    elmNode.value = sanitizedValue;

    elmNode.selectionStart =
      (selectionStart + diff > 0) ? selectionStart + diff : selectionStart;
    elmNode.selectionEnd =
      (selectionEnd + diff > 0) ? selectionEnd + diff : selectionEnd;
  }
}

$('document')
  .ready(() => {

    $("#input").on("input", handleInput);
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' id='input'/>