Отменить переопределенную пасту в JS - PullRequest
11 голосов
/ 25 апреля 2019

У меня переопределено событие paste .Я заметил, что из-за того, что поведение события по умолчанию запрещено, в настоящее время невозможно отменить «вставку» с помощью Ctrl + Z.

$(this).on('paste', function (evt) {
  // Get the pasted data via the Clipboard API.
  // evt.originalEvent must be used because this is jQuery, not pure JS.
  // https://stackoverflow.com/a/29831598
  var clipboardData = evt.originalEvent.clipboardData || window.clipboardData;
  var pastedData = clipboardData.getData('text/plain');

  // Trim the data and set the value.
  $(this).val($.trim(pastedData));

  // Prevent the data from actually being pasted.
  evt.preventDefault();
});

Есть ли способ переопределить функцию отмены или выполнить вышеуказанное по-другомучтобы Ctrl + Z работал?

Смежные вопросы

Ответы [ 3 ]

5 голосов
/ 16 мая 2019

Используйте

document.execCommand("insertText", false, $.trim(pastedData));

вместо

 $(this).val($.trim(pastedData));

Это сохранит историю отмен.

$('#inputElement').on('paste', function (evt) {
  var clipboardData = evt.originalEvent.clipboardData || window.clipboardData;
  var pastedData = clipboardData.getData('text/plain');
  this.select(); // To replace the entire text
  document.execCommand("insertText", false, $.trim(pastedData));
  evt.preventDefault();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="inputElement"></textarea>
3 голосов
/ 16 мая 2019

Возможное решение - реализовать стек отмены вручную.Алгоритм будет выглядеть примерно так:

  • Стек отмены запускается пустым.
  • Добавление прослушивателя для событий input, который помещает новую запись в «стек отмены» при вводеотличается от ввода последнего элемента стека ввода.Этот прослушиватель должен быть как минимум отменен, чтобы избежать однобуквенных элементов стека отмены.
  • Приемник событий paste также помещает запись в стек отмены при вызове.
  • Добавить keydown Слушатель, который перехватывает CTRL-Z и извлекает последнюю запись из стека отмены.

Это похоже на большую работу для чего-то, что уже встроено в браузеры, так что я надеюсьесть лучшее решение.

1 голос
/ 21 мая 2019

Я нашел способ заставить его работать.Начиная с этого ответа , я изменил его на .focus() вместо .select(), что исправляет вставку.Затем, чтобы сделать вставку работающей в Firefox, я должен был использовать запасной вариант, который не сохраняет историю отмены.Это нужно делать до тех пор, пока Firefox не исправит ошибку ( См. Отчет об ошибке ).

function insertAtCaretTrim(element, text) {
    element[0].focus();
    // Attempt to preserve edit history for undo.
    var inserted = document.execCommand("insertText", false, $.trim(text));
  
    // Fallback if execCommand is not supported.
    if (!inserted) {
        var caretPos = element[0].selectionStart;
        var value = element.val();

        // Get text before and after current selection.
        var prefix = value.substring(0, caretPos);
        var suffix = value.substring(element[0].selectionEnd, value.length);

        // Overwrite selected text with pasted text and trim. Limit to maxlength.
        element.val((prefix + $.trim(text) + suffix).substring(0, element.attr('maxlength')));

        // Set the cursor position to the end of the paste.
        caretPos += text.length;
        element.focus();
        element[0].setSelectionRange(caretPos, caretPos);
    }
}

var $inputs = $("input");

$inputs.each(function () {
    $(this).on('paste', function (evt) {
    var clipboardData = evt.originalEvent.clipboardData || window.clipboardData;
    var pastedData = clipboardData.getData('text/plain');

    // Trim the data and set the value.
    insertAtCaretTrim($(this), pastedData);
    
    evt.preventDefault();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" maxvalue="10" />

Код также находится в JSFIddle: https://jsfiddle.net/mf8v97en/5/

...